diff --git a/404.html b/404.html index f88ed5711..46523b408 100644 --- a/404.html +++ b/404.html @@ -6,9 +6,9 @@ 404 | The Paper Pilot - + - + @@ -48,7 +48,7 @@
- + \ No newline at end of file diff --git a/about/index.html b/about/index.html index 2d783d8ef..51617dd4f 100644 --- a/about/index.html +++ b/about/index.html @@ -6,12 +6,12 @@ About Me | The Paper Pilot - + - + - + @@ -50,8 +50,8 @@ -
Skip to content

About Me

I'm a software developer who likes making games and tools! I have a variety of interests, from game development to the fediverse to digital gardens.

I live in Dallas, Texas, USA with my wife and baby son. I work at Topaz Labs LLC as a Product Engineer. I develop their flagship product Topaz Photo AI.

Reach out to me:

These are old accounts I don't use anymore, but they are me:

- +
Skip to content

About Me

I'm a software developer who likes making games and tools! I have a variety of interests, from game development to the fediverse to digital gardens.

I live in Dallas, Texas, USA with my wife and baby son. I work at Topaz Labs LLC as a Product Engineer. I develop their flagship product Topaz Photo AI.

Reach out to me:

These are old accounts I don't use anymore, but they are me:

+ \ No newline at end of file diff --git a/assets/app.2CW3rSw8.js b/assets/app.CjRwD5T4.js similarity index 95% rename from assets/app.2CW3rSw8.js rename to assets/app.CjRwD5T4.js index 341b4ca7a..1530b2b37 100644 --- a/assets/app.2CW3rSw8.js +++ b/assets/app.CjRwD5T4.js @@ -1 +1 @@ -import{a6 as o,aQ as p,aR as u,aS as l,aT as c,aU as f,aV as d,aW as m,aX as h,aY as A,aZ as g,k as P,M as v,o as w,f as y,a_ as C,a$ as R,b0 as b,A as S}from"./chunks/framework.Sr2_9k8k.js";import{a as T}from"./chunks/theme.B2ZVa_Iv.js";function i(e){if(e.extends){const a=i(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const s=i(T),_=P({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=v();return w(()=>{y(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&C(),R(),b(),s.setup&&s.setup(),()=>S(s.Layout)}});async function E(){globalThis.__VITEPRESS__=!0;const e=V(),a=D();a.provide(u,e);const t=l(e.route);return a.provide(c,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),s.enhanceApp&&await s.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function D(){return h(_)}function V(){let e=o,a;return A(t=>{let n=g(t),r=null;return n&&(e&&(a=n),(e||a===n)&&(n=n.replace(/\.js$/,".lean.js")),r=import(n)),o&&(e=!1),r},s.NotFound)}o&&E().then(({app:e,router:a,data:t})=>{a.go().then(()=>{p(a.route,t.site),e.mount("#app")})});export{E as createApp}; +import{a6 as o,aQ as p,aR as u,aS as l,aT as c,aU as f,aV as d,aW as m,aX as h,aY as A,aZ as g,k as P,M as v,o as w,f as y,a_ as C,a$ as R,b0 as b,A as S}from"./chunks/framework.Sr2_9k8k.js";import{a as T}from"./chunks/theme.DpCaOULF.js";function i(e){if(e.extends){const a=i(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const s=i(T),_=P({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=v();return w(()=>{y(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&C(),R(),b(),s.setup&&s.setup(),()=>S(s.Layout)}});async function E(){globalThis.__VITEPRESS__=!0;const e=V(),a=D();a.provide(u,e);const t=l(e.route);return a.provide(c,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),s.enhanceApp&&await s.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function D(){return h(_)}function V(){let e=o,a;return A(t=>{let n=g(t),r=null;return n&&(e&&(a=n),(e||a===n)&&(n=n.replace(/\.js$/,".lean.js")),r=import(n)),o&&(e=!1),r},s.NotFound)}o&&E().then(({app:e,router:a,data:t})=>{a.go().then(()=>{p(a.route,t.site),e.mount("#app")})});export{E as createApp}; diff --git a/assets/changelog_index.md.DVgSDeNX.js b/assets/changelog_index.md.ilnyzBD3.js similarity index 99% rename from assets/changelog_index.md.DVgSDeNX.js rename to assets/changelog_index.md.ilnyzBD3.js index 201e7c5c0..2fb02af07 100644 --- a/assets/changelog_index.md.DVgSDeNX.js +++ b/assets/changelog_index.md.ilnyzBD3.js @@ -1,4 +1,5 @@ -import{_ as t,q as e,p as a,ag as s}from"./chunks/framework.Sr2_9k8k.js";const m=JSON.parse('{"title":"Garden Changelog","description":"","frontmatter":{"title":"Garden Changelog","prev":false,"next":false},"headers":[],"relativePath":"changelog/index.md","filePath":"changelog/index.md"}'),n={name:"changelog/index.md"},o=s(`

Garden Changelog

This feed starts when I formatted the site to be a Digital Garden. If you'd like to look further into this site's history, check here!

36 files changed, 517 insertions(+), 200 deletions(-)

Pushed on

This feed starts when I formatted the site to be a Digital Garden. If you'd like to look further into this site's history, check here!

36 files changed, 517 insertions(+), 200 deletions(-)

Pushed on
PageChanges
activitypub22 -----------
anarchism2 +-
atproto13 ++-----
chromatic-lattice10 ++++-
commune4 +-
consensus-democracy6 +--
debate64 ++++++++++++++++++++++++++++++
decentralized-identity45 ++++++++++++++++++++++
decentralized-moderation51 ++++++++++++++++++++++++
decentralized-social-media21 ++++++++++
decentralized12 +++---
digital-gardens2 +-
digital-locality77 ++++++++++++++++++-------------------
enshittification20 ++++++++++
everything-is-political53 +++++++++++++++++++++++++
federated-identity33 ----------------
fedi-v230 +++------------
fediverse16 +++-----
filter-bubbles10 ++---
incremental-social6 +--
leftism2 +-
local-communities2 +-
moderation36 +++++++++++++++++
my-personal-website2 +-
no-politics-rules74 +++++++++++++++++++++++++++++++++++
nostr8 ++--
objectivity2 +-
police-abolition8 ++--
social-media6 +--
the-small-web6 +--
this-knowledge-hub19 +++------
trans-athletes-in-sports2 +
video-essays6 ++-
virality43 +++++++++++++++++++++
vitepress2 +-
weird2 +-

19 files changed, 270 insertions(+), 35 deletions(-)

3 files changed, 4 insertions(+), 2 deletions(-)

Pushed on \\n. Last tended to \\n.","site/garden/anarchism/index.md":"Planted \\n. Last tended to \\n.","site/garden/artificial-intelligence/index.md":"Planted \\n. Last tended to \\n.","site/garden/atproto/index.md":"Planted \\n. Last tended to \\n.","site/garden/babble-buds/index.md":"Planted \\n. Last tended to \\n.","site/garden/capture-the-citadel/index.md":"Planted \\n. Last tended to \\n.","site/garden/chat-glue/index.md":"Planted \\n. Last tended to \\n.","site/garden/chromatic-lattice/index.md":"Planted \\n. Last tended to \\n.","site/garden/chronological/index.md":"Planted \\n. Last tended to \\n.","site/garden/cinny/index.md":"Planted \\n. Last tended to \\n.","site/garden/command-palettes/index.md":"Planted \\n. Last tended to \\n.","site/garden/commune/index.md":"Planted \\n. Last tended to \\n.","site/garden/consensus-democracy/index.md":"Planted \\n. Last tended to \\n.","site/garden/davey-wreden/index.md":"Planted \\n. Last tended to \\n.","site/garden/debate/index.md":"Planted \\n.","site/garden/decentralized-identity/index.md":"Planted \\n.","site/garden/decentralized-moderation/index.md":"Planted \\n.","site/garden/decentralized-social-media/index.md":"Planted \\n.","site/garden/decentralized/index.md":"Planted \\n. Last tended to \\n.","site/garden/dice-armor/index.md":"Planted \\n. Last tended to \\n.","site/garden/digital-gardens/index.md":"Planted \\n. Last tended to \\n.","site/garden/digital-locality/index.md":"Planted \\n. Last tended to \\n.","site/garden/direct-democracy/index.md":"Planted \\n. Last tended to \\n.","site/garden/enshittification/index.md":"Planted \\n.","site/garden/everything-is-political/index.md":"Planted \\n.","site/garden/fedi-v2/index.md":"Planted \\n. Last tended to \\n.","site/garden/fediverse/index.md":"Planted \\n. Last tended to \\n.","site/garden/filter-bubbles/index.md":"Planted \\n. Last tended to \\n.","site/garden/forgejo/index.md":"Planted \\n. Last tended to \\n.","site/garden/freeform-vs-chronological-dichotomy/index.md":"Planted \\n. Last tended to \\n.","site/garden/freeform/index.md":"Planted \\n. Last tended to \\n.","site/garden/game-dev-tree/index.md":"Planted \\n. Last tended to \\n.","site/garden/garden-rss/index.md":"Planted \\n. Last tended to \\n.","site/garden/gender-performativity/index.md":"Planted \\n.","site/garden/gender/index.md":"Planted \\n. Last tended to \\n.","site/garden/gerrymandering/index.md":"Planted \\n.","site/garden/guide-to-incrementals/appeal-to-developers/index.md":"Planted \\n. Last tended to \\n.","site/garden/guide-to-incrementals/appeal-to-players/index.md":"Planted \\n. Last tended to \\n.","site/garden/guide-to-incrementals/defining-the-genre/index.md":"Planted \\n. Last tended to \\n.","site/garden/guide-to-incrementals/index.md":"Planted \\n. Last tended to \\n.","site/garden/guide-to-incrementals/navigating-criticism/index.md":"Planted \\n. Last tended to \\n.","site/garden/guide-to-incrementals/what-is-content/index.md":"Planted \\n. Last tended to \\n.","site/garden/imperialism/index.md":"Planted \\n.","site/garden/incremental-social/index.md":"Planted \\n. Last tended to \\n.","site/garden/individualism/index.md":"Planted \\n. Last tended to \\n.","site/garden/ivy-road/index.md":"Planted \\n. Last tended to \\n.","site/garden/kronos/index.md":"Planted \\n. Last tended to \\n.","site/garden/leftism/index.md":"Planted \\n. Last tended to \\n.","site/garden/life-is-strange/index.md":"Planted \\n. Last tended to \\n.","site/garden/local-communities/index.md":"Planted \\n. Last tended to \\n.","site/garden/local-first-software/index.md":"Planted \\n.","site/garden/logseq/index.md":"Planted \\n. Last tended to \\n.","site/garden/matrix/index.md":"Planted \\n. Last tended to \\n.","site/garden/mbin/index.md":"Planted \\n. Last tended to \\n.","site/garden/moderation/index.md":"Planted \\n.","site/garden/mtx/index.md":"Planted \\n. Last tended to \\n.","site/garden/my-browser-stack/index.md":"Planted \\n.","site/garden/my-personal-website/index.md":"Planted \\n. Last tended to \\n.","site/garden/my-political-beliefs/index.md":"Planted \\n. Last tended to \\n.","site/garden/my-political-journey/index.md":"Planted \\n. Last tended to \\n.","site/garden/my-projects/index.md":"Planted \\n. Last tended to \\n.","site/garden/neoliberalism/index.md":"Planted \\n. Last tended to \\n.","site/garden/network-of-knowledge/index.md":"Planted \\n.","site/garden/no-politics-rules/index.md":"Planted \\n. Last tended to \\n.","site/garden/nostr/index.md":"Planted \\n. Last tended to \\n.","site/garden/objectivity/index.md":"Planted \\n. Last tended to \\n.","site/garden/open-source/index.md":"Planted \\n. Last tended to \\n.","site/garden/opti-speech/index.md":"Planted \\n. Last tended to \\n.","site/garden/orchard/index.md":"Planted \\n. Last tended to \\n.","site/garden/personality/index.md":"Planted \\n.","site/garden/planar-pioneers/index.md":"Planted \\n. Last tended to \\n.","site/garden/police-abolition/index.md":"Planted \\n. Last tended to \\n.","site/garden/political-quizzes/index.md":"Planted \\n.","site/garden/pre-order-bonuses/index.md":"Planted \\n. Last tended to \\n.","site/garden/premium-currency/index.md":"Planted \\n. Last tended to \\n.","site/garden/prescriptivism-vs-descriptivism/index.md":"Planted \\n.","site/garden/profectus/index.md":"Planted \\n. Last tended to \\n.","site/garden/representative-democracy/index.md":"Planted \\n. Last tended to \\n.","site/garden/scientific-constructivism/index.md":"Planted \\n.","site/garden/social-constructs/index.md":"Planted \\n. Last tended to \\n.","site/garden/social-media/index.md":"Planted \\n. Last tended to \\n.","site/garden/synapse/index.md":"Planted \\n. Last tended to \\n.","site/garden/technocracy/index.md":"Planted \\n. Last tended to \\n.","site/garden/the-beginner-s-guide/index.md":"Planted \\n. Last tended to \\n.","site/garden/the-cozy-web/index.md":"Planted \\n. Last tended to \\n.","site/garden/the-indieweb/amplification/index.md":"Planted \\n. Last tended to \\n.","site/garden/the-indieweb/signature-blocks/index.md":"Planted \\n. Last tended to \\n.","site/garden/the-small-web/index.md":"Planted \\n. Last tended to \\n.","site/garden/this-knowledge-hub/index.md":"Planted \\n. Last tended to \\n.","site/garden/trans-athletes-in-sports/index.md":"Planted \\n. Last tended to \\n.","site/garden/v-ecs/index.md":"Planted \\n. Last tended to \\n.","site/garden/video-essays/index.md":"Planted \\n. Last tended to \\n.","site/garden/video-game-monetization/index.md":"Planted \\n. Last tended to \\n.","site/garden/virality/index.md":"Planted \\n.","site/garden/vitepress/index.md":"Planted \\n. Last tended to \\n.","site/garden/wanderstop/index.md":"Planted \\n. Last tended to \\n.","site/garden/webrings/index.md":"Planted \\n. Last tended to \\n.","site/garden/weird/index.md":"Planted \\n. Last tended to \\n.","site/garden/a-plea-to-organize/index.md":"Planted \\n. Last tended to \\n.","site/garden/art-is-never-complete/index.md":"Planted \\n.","site/now/index.md":"Planted \\n. Last tended to \\n.","site/guide-to-incrementals/index.md":"Planted \\n. Last tended to \\n.","site/guide-to-incrementals/design/criticism/index.md":"Planted \\n. Last tended to \\n.","site/guide-to-incrementals/ludology/appeal-developers/index.md":"Planted \\n. Last tended to \\n.","site/guide-to-incrementals/ludology/appeal-gamers/index.md":"Planted \\n. Last tended to \\n.","site/guide-to-incrementals/ludology/content/index.md":"Planted \\n. Last tended to \\n.","site/guide-to-incrementals/ludology/definition/index.md":"Planted \\n. Last tended to \\n."}`);export{e as d}; diff --git a/assets/chunks/git.data.D-Ga3RhB.js b/assets/chunks/git.data.D-Ga3RhB.js deleted file mode 100644 index 8869cd65b..000000000 --- a/assets/chunks/git.data.D-Ga3RhB.js +++ /dev/null @@ -1 +0,0 @@ -const e=JSON.parse(`{"site/garden/anarchism/index.md":"Planted \\n. Last tended to \\n.","site/garden/art-is-never-complete/index.md":"Planted \\n.","site/garden/artificial-intelligence/index.md":"Planted \\n. Last tended to \\n.","site/garden/atproto/index.md":"Planted \\n. Last tended to \\n.","site/garden/babble-buds/index.md":"Planted \\n. Last tended to \\n.","site/garden/capture-the-citadel/index.md":"Planted \\n. Last tended to \\n.","site/garden/chat-glue/index.md":"Planted \\n. Last tended to \\n.","site/garden/chromatic-lattice/index.md":"Planted \\n. Last tended to \\n.","site/garden/chronological/index.md":"Planted \\n. Last tended to \\n.","site/garden/cinny/index.md":"Planted \\n. Last tended to \\n.","site/garden/command-palettes/index.md":"Planted \\n. Last tended to \\n.","site/garden/commune/index.md":"Planted \\n. Last tended to \\n.","site/garden/consensus-democracy/index.md":"Planted \\n. Last tended to \\n.","site/garden/davey-wreden/index.md":"Planted \\n. Last tended to \\n.","site/garden/debate/index.md":"Planted \\n.","site/garden/decentralized-identity/index.md":"Planted \\n.","site/garden/decentralized-moderation/index.md":"Planted \\n.","site/garden/decentralized-social-media/index.md":"Planted \\n.","site/garden/decentralized/index.md":"Planted \\n. Last tended to \\n.","site/garden/dice-armor/index.md":"Planted \\n. Last tended to \\n.","site/garden/digital-gardens/index.md":"Planted \\n. Last tended to \\n.","site/garden/digital-locality/index.md":"Planted \\n. Last tended to \\n.","site/garden/direct-democracy/index.md":"Planted \\n. Last tended to \\n.","site/garden/enshittification/index.md":"Planted \\n.","site/garden/everything-is-political/index.md":"Planted \\n.","site/garden/fedi-v2/index.md":"Planted \\n. Last tended to \\n.","site/garden/fediverse/index.md":"Planted \\n. Last tended to \\n.","site/garden/filter-bubbles/index.md":"Planted \\n. Last tended to \\n.","site/garden/forgejo/index.md":"Planted \\n. Last tended to \\n.","site/garden/freeform-vs-chronological-dichotomy/index.md":"Planted \\n. Last tended to \\n.","site/garden/freeform/index.md":"Planted \\n. Last tended to \\n.","site/garden/game-dev-tree/index.md":"Planted \\n. Last tended to \\n.","site/garden/garden-rss/index.md":"Planted \\n. Last tended to \\n.","site/garden/gender-performativity/index.md":"Planted \\n.","site/garden/gender/index.md":"Planted \\n. Last tended to \\n.","site/garden/gerrymandering/index.md":"Planted \\n.","site/garden/guide-to-incrementals/appeal-to-developers/index.md":"Planted \\n. Last tended to \\n.","site/garden/guide-to-incrementals/appeal-to-players/index.md":"Planted \\n. Last tended to \\n.","site/garden/guide-to-incrementals/defining-the-genre/index.md":"Planted \\n. Last tended to \\n.","site/garden/guide-to-incrementals/index.md":"Planted \\n. Last tended to \\n.","site/garden/guide-to-incrementals/navigating-criticism/index.md":"Planted \\n. Last tended to \\n.","site/garden/guide-to-incrementals/what-is-content/index.md":"Planted \\n. Last tended to \\n.","site/garden/imperialism/index.md":"Planted \\n.","site/garden/incremental-social/index.md":"Planted \\n. Last tended to \\n.","site/garden/individualism/index.md":"Planted \\n. Last tended to \\n.","site/garden/ivy-road/index.md":"Planted \\n. Last tended to \\n.","site/garden/kronos/index.md":"Planted \\n. Last tended to \\n.","site/garden/leftism/index.md":"Planted \\n. Last tended to \\n.","site/garden/life-is-strange/index.md":"Planted \\n. Last tended to \\n.","site/garden/local-communities/index.md":"Planted \\n. Last tended to \\n.","site/garden/local-first-software/index.md":"Planted \\n.","site/garden/logseq/index.md":"Planted \\n. Last tended to \\n.","site/garden/matrix/index.md":"Planted \\n. Last tended to \\n.","site/garden/mbin/index.md":"Planted \\n. Last tended to \\n.","site/garden/moderation/index.md":"Planted \\n.","site/garden/mtx/index.md":"Planted \\n. Last tended to \\n.","site/garden/my-browser-stack/index.md":"Planted \\n.","site/garden/my-personal-website/index.md":"Planted \\n. Last tended to \\n.","site/garden/my-political-beliefs/index.md":"Planted \\n. Last tended to \\n.","site/garden/my-political-journey/index.md":"Planted \\n. Last tended to \\n.","site/garden/my-projects/index.md":"Planted \\n. Last tended to \\n.","site/garden/neoliberalism/index.md":"Planted \\n. Last tended to \\n.","site/garden/network-of-knowledge/index.md":"Planted \\n.","site/garden/no-politics-rules/index.md":"Planted \\n.","site/garden/nostr/index.md":"Planted \\n. Last tended to \\n.","site/garden/objectivity/index.md":"Planted \\n. Last tended to \\n.","site/garden/open-source/index.md":"Planted \\n. Last tended to \\n.","site/garden/opti-speech/index.md":"Planted \\n. Last tended to \\n.","site/garden/orchard/index.md":"Planted \\n. Last tended to \\n.","site/garden/personality/index.md":"Planted \\n.","site/garden/planar-pioneers/index.md":"Planted \\n. Last tended to \\n.","site/garden/police-abolition/index.md":"Planted \\n. Last tended to \\n.","site/garden/political-quizzes/index.md":"Planted \\n.","site/garden/pre-order-bonuses/index.md":"Planted \\n. Last tended to \\n.","site/garden/premium-currency/index.md":"Planted \\n. Last tended to \\n.","site/garden/prescriptivism-vs-descriptivism/index.md":"Planted \\n.","site/garden/profectus/index.md":"Planted \\n. Last tended to \\n.","site/garden/representative-democracy/index.md":"Planted \\n. Last tended to \\n.","site/garden/scientific-constructivism/index.md":"Planted \\n.","site/garden/social-constructs/index.md":"Planted \\n. Last tended to \\n.","site/garden/social-media/index.md":"Planted \\n. Last tended to \\n.","site/garden/synapse/index.md":"Planted \\n. Last tended to \\n.","site/garden/technocracy/index.md":"Planted \\n. Last tended to \\n.","site/garden/the-beginner-s-guide/index.md":"Planted \\n. Last tended to \\n.","site/garden/the-cozy-web/index.md":"Planted \\n. Last tended to \\n.","site/garden/the-indieweb/amplification/index.md":"Planted \\n. Last tended to \\n.","site/garden/the-indieweb/signature-blocks/index.md":"Planted \\n. Last tended to \\n.","site/garden/the-small-web/index.md":"Planted \\n. Last tended to \\n.","site/garden/this-knowledge-hub/index.md":"Planted \\n. Last tended to \\n.","site/garden/trans-athletes-in-sports/index.md":"Planted \\n. Last tended to \\n.","site/garden/v-ecs/index.md":"Planted \\n. Last tended to \\n.","site/garden/video-essays/index.md":"Planted \\n. Last tended to \\n.","site/garden/video-game-monetization/index.md":"Planted \\n. Last tended to \\n.","site/garden/virality/index.md":"Planted \\n.","site/garden/vitepress/index.md":"Planted \\n. Last tended to \\n.","site/garden/wanderstop/index.md":"Planted \\n. Last tended to \\n.","site/garden/webrings/index.md":"Planted \\n. Last tended to \\n.","site/garden/weird/index.md":"Planted \\n. Last tended to \\n.","site/now/index.md":"Planted \\n. Last tended to \\n.","site/garden/advent-incremental/index.md":"Planted \\n. Last tended to \\n.","site/garden/a-plea-to-organize/index.md":"Planted \\n. Last tended to \\n.","site/guide-to-incrementals/index.md":"Planted \\n. Last tended to \\n.","site/guide-to-incrementals/design/criticism/index.md":"Planted \\n. Last tended to \\n.","site/guide-to-incrementals/ludology/appeal-developers/index.md":"Planted \\n. Last tended to \\n.","site/guide-to-incrementals/ludology/appeal-gamers/index.md":"Planted \\n. Last tended to \\n.","site/guide-to-incrementals/ludology/content/index.md":"Planted \\n. Last tended to \\n.","site/guide-to-incrementals/ludology/definition/index.md":"Planted \\n. Last tended to \\n."}`);export{e as d}; diff --git a/assets/chunks/theme.B2ZVa_Iv.js b/assets/chunks/theme.DpCaOULF.js similarity index 99% rename from assets/chunks/theme.B2ZVa_Iv.js rename to assets/chunks/theme.DpCaOULF.js index 03f5dc8f9..7fefad0e8 100644 --- a/assets/chunks/theme.B2ZVa_Iv.js +++ b/assets/chunks/theme.DpCaOULF.js @@ -1,4 +1,4 @@ -const __vite__fileDeps=["assets/chunks/VPLocalSearchBox.WgSDvytm.js","assets/chunks/framework.Sr2_9k8k.js"],__vite__mapDeps=i=>i.map(i=>__vite__fileDeps[i]); +const __vite__fileDeps=["assets/chunks/VPLocalSearchBox.CGFBigMq.js","assets/chunks/framework.Sr2_9k8k.js"],__vite__mapDeps=i=>i.map(i=>__vite__fileDeps[i]); import{u as j,r as Ge,w as Ct,i as $d,t as Vm,c as Hm,o as Nn,n as qc,g as Gm,a as Wm,b as ma,d as gr,e as ke,f as Ri,h as zr,j as $m,k as Be,l as Xd,s as Rn,m as Wn,p as Y,q as fe,v as yt,x as Yc,y as vr,z as Xm,A as eh,F as xt,B as qm,C as cn,D as $e,E as ye,G as Jt,H as De,I as Fe,J as ue,K as Ht,L as ft,T as Zc,_ as Ye,M as Ym,N as Zm,O as Jm,P as Jc,Q as me,R as Wt,S as $t,U as is,V as Kl,W as qd,X as Km,Y as jm,Z as Aa,$ as Bs,a0 as Yd,a1 as Vr,a2 as ia,a3 as Qm,a4 as jl,a5 as Zd,a6 as Ta,a7 as eg,a8 as tg,a9 as Jd,aa as ng,ab as ig,ac as sg,ad as rg,ae as og,af as ag}from"./framework.Sr2_9k8k.js";/** * @license * Copyright 2010-2024 Three.js Authors @@ -3945,4 +3945,4 @@ void main() { alpha += max(0., snoise(vec3(gl_FragCoord.xy / 304., uTime / 4.))); gl_FragColor = vec4(mix(uColor, vec3(0.), alpha), uColor == vec3(0.) ? alpha : 1.); } -`;return(p,y)=>{const _=cn("TresShapeGeometry"),x=cn("TresShaderMaterial"),A=cn("TresMesh"),b=cn("TresGroup");return j(i)?(Y(),$e(b,{key:0,ref_key:"groupRef",ref:g,renderOrder:1},{default:ye(()=>[(Y(!0),fe(xt,null,Jt(l.value*c.value,E=>(Y(),$e(A,{position:[(E%c.value-c.value/2)*304,(Math.floor((E-1)/c.value)-l.value/2)*304,1]},{default:ye(()=>[Fe(_,{args:[j(a)]},null,8,["args"]),Fe(x,{vertexShader:Bw,fragmentShader:m,uniforms:v,blending:j(ga),stencilWrite:p.mask!=null,stencilRef:p.mask??0,stencilFunc:j(Zf),stencilFail:j(Bn),stencilZFail:j(Bn),stencilZPass:j(Bn)},null,8,["blending","stencilWrite","stencilRef","stencilFunc","stencilFail","stencilZFail","stencilZPass"])]),_:2},1032,["position"]))),256))]),_:1},512)):De("",!0)}}}),Vw=Be({__name:"VPBadge",props:{text:{},type:{default:"tip"}},setup(s){return(e,t)=>(Y(),fe("span",{class:yt(["VPBadge",e.type])},[ue(e.$slots,"default",{},()=>[Ht(ft(e.text),1)])],2))}}),Hw={key:0,class:"VPBackdrop"},Gw=Be({__name:"VPBackdrop",props:{show:{type:Boolean}},setup(s){return(e,t)=>(Y(),$e(Zc,{name:"fade"},{default:ye(()=>[e.show?(Y(),fe("div",Hw)):De("",!0)]),_:1}))}}),Ww=Ye(Gw,[["__scopeId","data-v-c79a1216"]]),ot=Ym;function $w(s,e){let t,n=!1;return()=>{t&&clearTimeout(t),n?t=setTimeout(s,e):(s(),(n=!0)&&setTimeout(()=>n=!1,e))}}function Wc(s){return/^\//.test(s)?s:`/${s}`}function Hu(s){const{pathname:e,search:t,hash:n,protocol:i}=new URL(s,"http://a.com");if(Zm(s)||s.startsWith("#")||!i.startsWith("http")||!Jm(e))return s;const{site:r}=ot(),o=e.endsWith("/")||e.endsWith(".html")?s:s.replace(/(?:(^\.+)\/)?.*$/,`$1${e.replace(/(\.md)?$/,r.value.cleanUrls?"":".html")}${t}${n}`);return Jc(o)}function to({correspondingLink:s=!1}={}){const{site:e,localeIndex:t,page:n,theme:i,hash:r}=ot(),o=ke(()=>{var l,c;return{label:(l=e.value.locales[t.value])==null?void 0:l.label,link:((c=e.value.locales[t.value])==null?void 0:c.link)||(t.value==="root"?"/":`/${t.value}/`)}});return{localeLinks:ke(()=>Object.entries(e.value.locales).flatMap(([l,c])=>o.value.label===c.label?[]:{text:c.label,link:Xw(c.link||(l==="root"?"/":`/${l}/`),i.value.i18nRouting!==!1&&s,n.value.relativePath.slice(o.value.link.length-1),!e.value.cleanUrls)+r.value})),currentLang:o}}function Xw(s,e,t,n){return e?s.replace(/\/$/,"")+Wc(t.replace(/(^|\/)index\.md$/,"$1").replace(/\.md$/,n?".html":"")):s}const qw=s=>(Wt("data-v-d6be1790"),s=s(),$t(),s),Yw={class:"NotFound"},Zw={class:"code"},Jw={class:"title"},Kw=qw(()=>me("div",{class:"divider"},null,-1)),jw={class:"quote"},Qw={class:"action"},e1=["href","aria-label"],t1=Be({__name:"NotFound",setup(s){const{theme:e}=ot(),{currentLang:t}=to();return(n,i)=>{var r,o,a,l,c;return Y(),fe("div",Yw,[me("p",Zw,ft(((r=j(e).notFound)==null?void 0:r.code)??"404"),1),me("h1",Jw,ft(((o=j(e).notFound)==null?void 0:o.title)??"PAGE NOT FOUND"),1),Kw,me("blockquote",jw,ft(((a=j(e).notFound)==null?void 0:a.quote)??"But if you don't change your direction, and if you keep looking, you may end up where you are heading."),1),me("div",Qw,[me("a",{class:"link",href:j(Jc)(j(t).link),"aria-label":((l=j(e).notFound)==null?void 0:l.linkLabel)??"go to home"},ft(((c=j(e).notFound)==null?void 0:c.linkText)??"Take me home"),9,e1)])])}}}),n1=Ye(t1,[["__scopeId","data-v-d6be1790"]]);function Am(s,e){if(Array.isArray(s))return pa(s);if(s==null)return[];e=Wc(e);const t=Object.keys(s).sort((i,r)=>r.split("/").length-i.split("/").length).find(i=>e.startsWith(Wc(i))),n=t?s[t]:[];return Array.isArray(n)?pa(n):pa(n.items,n.base)}function i1(s){const e=[];let t=0;for(const n in s){const i=s[n];if(i.items){t=e.push(i);continue}e[t]||e.push({items:[]}),e[t].items.push(i)}return e}function s1(s){const e=[];function t(n){for(const i of n)i.text&&i.link&&e.push({text:i.text,link:i.link,docFooterText:i.docFooterText}),i.items&&t(i.items)}return t(s),e}function $c(s,e){return Array.isArray(e)?e.some(t=>$c(s,t)):is(s,e.link)?!0:e.items?$c(s,e.items):!1}function pa(s,e){return[...s].map(t=>{const n={...t},i=n.base||e;return i&&n.link&&(n.link=i+n.link),n.items&&(n.items=pa(n.items,i)),n})}function fi(){const{frontmatter:s,page:e,theme:t}=ot(),n=Kl("(min-width: 960px)"),i=Ge(!1),r=ke(()=>{const v=t.value.sidebar,m=e.value.relativePath;return v?Am(v,m):[]}),o=Ge(r.value);Ct(r,(v,m)=>{JSON.stringify(v)!==JSON.stringify(m)&&(o.value=r.value)});const a=ke(()=>s.value.sidebar!==!1&&o.value.length>0&&s.value.layout!=="home"),l=ke(()=>c?s.value.aside==null?t.value.aside==="left":s.value.aside==="left":!1),c=ke(()=>s.value.layout==="home"?!1:s.value.aside!=null?!!s.value.aside:t.value.aside!==!1),u=ke(()=>a.value&&n.value),h=ke(()=>a.value?i1(o.value):[]);function d(){i.value=!0}function f(){i.value=!1}function g(){i.value?f():d()}return{isOpen:i,sidebar:o,sidebarGroups:h,hasSidebar:a,hasAside:c,leftAside:l,isSidebarEnabled:u,open:d,close:f,toggle:g}}function r1(s,e){let t;Ri(()=>{t=s.value?document.activeElement:void 0}),Nn(()=>{window.addEventListener("keyup",n)}),Wn(()=>{window.removeEventListener("keyup",n)});function n(i){i.key==="Escape"&&s.value&&(e(),t==null||t.focus())}}function o1(s){const{page:e,hash:t}=ot(),n=Ge(!1),i=ke(()=>s.value.collapsed!=null),r=ke(()=>!!s.value.link),o=Ge(!1),a=()=>{o.value=is(e.value.relativePath,s.value.link)};Ct([e,s,t],a),Nn(a);const l=ke(()=>o.value?!0:s.value.items?$c(e.value.relativePath,s.value.items):!1),c=ke(()=>!!(s.value.items&&s.value.items.length));Ri(()=>{n.value=!!(i.value&&s.value.collapsed)}),qd(()=>{(o.value||l.value)&&(n.value=!1)});function u(){i.value&&(n.value=!n.value)}return{collapsed:n,collapsible:i,isLink:r,isActiveLink:o,hasActiveLink:l,hasChildren:c,toggle:u}}function a1(){const{hasSidebar:s}=fi(),e=Kl("(min-width: 960px)"),t=Kl("(min-width: 1280px)");return{isAsideEnabled:ke(()=>!t.value&&!e.value?!1:s.value?t.value:e.value)}}const Xc=[];function Tm(s){return typeof s.outline=="object"&&!Array.isArray(s.outline)&&s.outline.label||s.outlineTitle||"On this page"}function Gu(s){const e=[...document.querySelectorAll(".VPDoc :where(h1,h2,h3,h4,h5,h6)")].filter(t=>t.id&&t.hasChildNodes()).map(t=>{const n=Number(t.tagName[1]);return{element:t,title:l1(t),link:"#"+t.id,level:n}});return c1(e,s)}function l1(s){let e="";for(const t of s.childNodes)if(t.nodeType===1){if(t.classList.contains("VPBadge")||t.classList.contains("header-anchor")||t.classList.contains("ignore-header"))continue;e+=t.textContent}else t.nodeType===3&&(e+=t.textContent);return e.trim()}function c1(s,e){if(e===!1)return[];const t=(typeof e=="object"&&!Array.isArray(e)?e.level:e)||2,[n,i]=typeof t=="number"?[t,t]:t==="deep"?[2,6]:t;s=s.filter(o=>o.level>=n&&o.level<=i),Xc.length=0;for(const{element:o,link:a}of s)Xc.push({element:o,link:a});const r=[];e:for(let o=0;o=0;l--){const c=s[l];if(c.level{requestAnimationFrame(r),window.addEventListener("scroll",n)}),Km(()=>{o(location.hash)}),Wn(()=>{window.removeEventListener("scroll",n)});function r(){if(!t.value)return;const a=window.scrollY,l=window.innerHeight,c=document.body.offsetHeight,u=Math.abs(a+l-c)<1,h=Xc.map(({element:f,link:g})=>({link:g,top:h1(f)})).filter(({top:f})=>!Number.isNaN(f)).sort((f,g)=>f.top-g.top);if(!h.length){o(null);return}if(a<1){o(null);return}if(u){o(h[h.length-1].link);return}let d=null;for(const{link:f,top:g}of h){if(g>a+jm()+4)break;d=f}o(d)}function o(a){i&&i.classList.remove("active"),a==null?i=null:i=s.value.querySelector(`a[href="${decodeURIComponent(a)}"]`);const l=i;l?(l.classList.add("active"),e.value.style.top=l.offsetTop+39+"px",e.value.style.opacity="1"):(e.value.style.top="33px",e.value.style.opacity="0")}}function h1(s){let e=0;for(;s!==document.body;){if(s===null)return NaN;e+=s.offsetTop,s=s.offsetParent}return e}const d1=["href","title"],f1=Be({__name:"VPDocOutlineItem",props:{headers:{},root:{type:Boolean}},setup(s){function e({target:t}){const n=t.href.split("#")[1],i=document.getElementById(decodeURIComponent(n));i==null||i.focus({preventScroll:!0})}return(t,n)=>{const i=cn("VPDocOutlineItem",!0);return Y(),fe("ul",{class:yt(["VPDocOutlineItem",t.root?"root":"nested"])},[(Y(!0),fe(xt,null,Jt(t.headers,({children:r,link:o,title:a})=>(Y(),fe("li",null,[me("a",{class:"outline-link",href:o,onClick:e,title:a},ft(a),9,d1),r!=null&&r.length?(Y(),$e(i,{key:0,headers:r},null,8,["headers"])):De("",!0)]))),256))],2)}}}),Em=Ye(f1,[["__scopeId","data-v-b933a997"]]),p1={class:"content"},m1={"aria-level":"2",class:"outline-title",id:"doc-outline-aria-label",role:"heading"},g1=Be({__name:"VPDocAsideOutline",setup(s){const{frontmatter:e,theme:t}=ot(),n=Rn([]);Aa(()=>{n.value=Gu(e.value.outline??t.value.outline)});const i=Ge(),r=Ge();return u1(i,r),(o,a)=>(Y(),fe("nav",{"aria-labelledby":"doc-outline-aria-label",class:yt(["VPDocAsideOutline",{"has-outline":n.value.length>0}]),ref_key:"container",ref:i},[me("div",p1,[me("div",{class:"outline-marker",ref_key:"marker",ref:r},null,512),me("div",m1,ft(j(Tm)(j(t))),1),Fe(Em,{headers:n.value,root:!0},null,8,["headers"])])],2))}}),v1=Ye(g1,[["__scopeId","data-v-a5bbad30"]]),_1={class:"VPDocAsideCarbonAds"},y1=Be({__name:"VPDocAsideCarbonAds",props:{carbonAds:{}},setup(s){const e=()=>null;return(t,n)=>(Y(),fe("div",_1,[Fe(j(e),{"carbon-ads":t.carbonAds},null,8,["carbon-ads"])]))}}),x1=s=>(Wt("data-v-3f215769"),s=s(),$t(),s),M1={class:"VPDocAside"},b1=x1(()=>me("div",{class:"spacer"},null,-1)),S1=Be({__name:"VPDocAside",setup(s){const{theme:e}=ot();return(t,n)=>(Y(),fe("div",M1,[ue(t.$slots,"aside-top",{},void 0,!0),ue(t.$slots,"aside-outline-before",{},void 0,!0),Fe(v1),ue(t.$slots,"aside-outline-after",{},void 0,!0),b1,ue(t.$slots,"aside-ads-before",{},void 0,!0),j(e).carbonAds?(Y(),$e(y1,{key:0,"carbon-ads":j(e).carbonAds},null,8,["carbon-ads"])):De("",!0),ue(t.$slots,"aside-ads-after",{},void 0,!0),ue(t.$slots,"aside-bottom",{},void 0,!0)]))}}),w1=Ye(S1,[["__scopeId","data-v-3f215769"]]);function A1(){const{theme:s,page:e}=ot();return ke(()=>{const{text:t="Edit this page",pattern:n=""}=s.value.editLink||{};let i;return typeof n=="function"?i=n(e.value):i=n.replace(/:path/g,e.value.filePath),{url:i,text:t}})}function T1(){const{page:s,theme:e,frontmatter:t}=ot();return ke(()=>{var c,u,h,d,f,g,v,m;const n=Am(e.value.sidebar,s.value.relativePath),i=s1(n),r=E1(i,p=>p.link.replace(/[?#].*$/,"")),o=r.findIndex(p=>is(s.value.relativePath,p.link)),a=((c=e.value.docFooter)==null?void 0:c.prev)===!1&&!t.value.prev||t.value.prev===!1,l=((u=e.value.docFooter)==null?void 0:u.next)===!1&&!t.value.next||t.value.next===!1;return{prev:a?void 0:{text:(typeof t.value.prev=="string"?t.value.prev:typeof t.value.prev=="object"?t.value.prev.text:void 0)??((h=r[o-1])==null?void 0:h.docFooterText)??((d=r[o-1])==null?void 0:d.text),link:(typeof t.value.prev=="object"?t.value.prev.link:void 0)??((f=r[o-1])==null?void 0:f.link)},next:l?void 0:{text:(typeof t.value.next=="string"?t.value.next:typeof t.value.next=="object"?t.value.next.text:void 0)??((g=r[o+1])==null?void 0:g.docFooterText)??((v=r[o+1])==null?void 0:v.text),link:(typeof t.value.next=="object"?t.value.next.link:void 0)??((m=r[o+1])==null?void 0:m.link)}}})}function E1(s,e){const t=new Set;return s.filter(n=>{const i=e(n);return t.has(i)?!1:t.add(i)})}const Gn=Be({__name:"VPLink",props:{tag:{},href:{},noIcon:{type:Boolean},target:{},rel:{}},setup(s){const e=s,t=ke(()=>e.tag??(e.href?"a":"span")),n=ke(()=>e.href&&Yd.test(e.href)||e.target==="_blank");return(i,r)=>(Y(),$e(Bs(t.value),{class:yt(["VPLink",{link:i.href,"vp-external-link-icon":n.value,"no-icon":i.noIcon}]),href:i.href?j(Hu)(i.href):void 0,target:i.target??(n.value?"_blank":void 0),rel:i.rel??(n.value?"noreferrer":void 0)},{default:ye(()=>[ue(i.$slots,"default")]),_:3},8,["class","href","target","rel"]))}}),C1={class:"VPLastUpdated"},P1=["datetime"],R1=Be({__name:"VPDocFooterLastUpdated",setup(s){const{theme:e,page:t,frontmatter:n,lang:i}=ot(),r=ke(()=>new Date(n.value.lastUpdated??t.value.lastUpdated)),o=ke(()=>r.value.toISOString()),a=Ge("");return Nn(()=>{Ri(()=>{var l,c,u;a.value=new Intl.DateTimeFormat((c=(l=e.value.lastUpdated)==null?void 0:l.formatOptions)!=null&&c.forceLocale?i.value:void 0,((u=e.value.lastUpdated)==null?void 0:u.formatOptions)??{dateStyle:"short",timeStyle:"short"}).format(r.value)})}),(l,c)=>{var u;return Y(),fe("p",C1,[Ht(ft(((u=j(e).lastUpdated)==null?void 0:u.text)||j(e).lastUpdatedText||"Last updated")+": ",1),me("time",{datetime:o.value},ft(a.value),9,P1)])}}}),I1=Ye(R1,[["__scopeId","data-v-7e05ebdb"]]),Cm=s=>(Wt("data-v-d4a0bba5"),s=s(),$t(),s),L1={key:0,class:"VPDocFooter"},N1={key:0,class:"edit-info"},D1={key:0,class:"edit-link"},U1=Cm(()=>me("span",{class:"vpi-square-pen edit-link-icon"},null,-1)),O1={key:1,class:"last-updated"},F1={key:1,class:"prev-next","aria-labelledby":"doc-footer-aria-label"},k1=Cm(()=>me("span",{class:"visually-hidden",id:"doc-footer-aria-label"},"Pager",-1)),B1={class:"pager"},z1=["innerHTML"],V1=["innerHTML"],H1={class:"pager"},G1=["innerHTML"],W1=["innerHTML"],$1=Be({__name:"VPDocFooter",setup(s){const{theme:e,page:t,frontmatter:n}=ot(),i=A1(),r=T1(),o=ke(()=>e.value.editLink&&n.value.editLink!==!1),a=ke(()=>t.value.lastUpdated&&n.value.lastUpdated!==!1),l=ke(()=>o.value||a.value||r.value.prev||r.value.next);return(c,u)=>{var h,d,f,g;return l.value?(Y(),fe("footer",L1,[ue(c.$slots,"doc-footer-before",{},void 0,!0),o.value||a.value?(Y(),fe("div",N1,[o.value?(Y(),fe("div",D1,[Fe(Gn,{class:"edit-link-button",href:j(i).url,"no-icon":!0},{default:ye(()=>[U1,Ht(" "+ft(j(i).text),1)]),_:1},8,["href"])])):De("",!0),a.value?(Y(),fe("div",O1,[Fe(I1)])):De("",!0)])):De("",!0),(h=j(r).prev)!=null&&h.link||(d=j(r).next)!=null&&d.link?(Y(),fe("nav",F1,[k1,me("div",B1,[(f=j(r).prev)!=null&&f.link?(Y(),$e(Gn,{key:0,class:"pager-link prev",href:j(r).prev.link},{default:ye(()=>{var v;return[me("span",{class:"desc",innerHTML:((v=j(e).docFooter)==null?void 0:v.prev)||"Previous page"},null,8,z1),me("span",{class:"title",innerHTML:j(r).prev.text},null,8,V1)]}),_:1},8,["href"])):De("",!0)]),me("div",H1,[(g=j(r).next)!=null&&g.link?(Y(),$e(Gn,{key:0,class:"pager-link next",href:j(r).next.link},{default:ye(()=>{var v;return[me("span",{class:"desc",innerHTML:((v=j(e).docFooter)==null?void 0:v.next)||"Next page"},null,8,G1),me("span",{class:"title",innerHTML:j(r).next.text},null,8,W1)]}),_:1},8,["href"])):De("",!0)])])):De("",!0)])):De("",!0)}}}),X1=Ye($1,[["__scopeId","data-v-d4a0bba5"]]),q1=s=>(Wt("data-v-39a288b8"),s=s(),$t(),s),Y1={class:"container"},Z1=q1(()=>me("div",{class:"aside-curtain"},null,-1)),J1={class:"aside-container"},K1={class:"aside-content"},j1={class:"content"},Q1={class:"content-container"},eA={class:"main"},tA=Be({__name:"VPDoc",setup(s){const{theme:e}=ot(),t=Vr(),{hasSidebar:n,hasAside:i,leftAside:r}=fi(),o=ke(()=>t.path.replace(/[./]+/g,"_").replace(/_html$/,""));return(a,l)=>{const c=cn("Content");return Y(),fe("div",{class:yt(["VPDoc",{"has-sidebar":j(n),"has-aside":j(i)}])},[ue(a.$slots,"doc-top",{},void 0,!0),me("div",Y1,[j(i)?(Y(),fe("div",{key:0,class:yt(["aside",{"left-aside":j(r)}])},[Z1,me("div",J1,[me("div",K1,[Fe(w1,null,{"aside-top":ye(()=>[ue(a.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":ye(()=>[ue(a.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":ye(()=>[ue(a.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":ye(()=>[ue(a.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":ye(()=>[ue(a.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":ye(()=>[ue(a.$slots,"aside-ads-after",{},void 0,!0)]),_:3})])])],2)):De("",!0),me("div",j1,[me("div",Q1,[ue(a.$slots,"doc-before",{},void 0,!0),me("main",eA,[Fe(c,{class:yt(["vp-doc",[o.value,j(e).externalLinkIcon&&"external-link-icon-enabled"]])},null,8,["class"])]),Fe(X1,null,{"doc-footer-before":ye(()=>[ue(a.$slots,"doc-footer-before",{},void 0,!0)]),_:3}),ue(a.$slots,"doc-after",{},void 0,!0)])])]),ue(a.$slots,"doc-bottom",{},void 0,!0)],2)}}}),nA=Ye(tA,[["__scopeId","data-v-39a288b8"]]),iA=Be({__name:"VPButton",props:{tag:{},size:{default:"medium"},theme:{default:"brand"},text:{},href:{},target:{},rel:{}},setup(s){const e=s,t=ke(()=>e.href&&Yd.test(e.href)),n=ke(()=>e.tag||e.href?"a":"button");return(i,r)=>(Y(),$e(Bs(n.value),{class:yt(["VPButton",[i.size,i.theme]]),href:i.href?j(Hu)(i.href):void 0,target:e.target??(t.value?"_blank":void 0),rel:e.rel??(t.value?"noreferrer":void 0)},{default:ye(()=>[Ht(ft(i.text),1)]),_:1},8,["class","href","target","rel"]))}}),sA=Ye(iA,[["__scopeId","data-v-cad61b99"]]),rA=["src","alt"],oA=Be({inheritAttrs:!1,__name:"VPImage",props:{image:{},alt:{}},setup(s){return(e,t)=>{const n=cn("VPImage",!0);return e.image?(Y(),fe(xt,{key:0},[typeof e.image=="string"||"src"in e.image?(Y(),fe("img",ia({key:0,class:"VPImage"},typeof e.image=="string"?e.$attrs:{...e.image,...e.$attrs},{src:j(Jc)(typeof e.image=="string"?e.image:e.image.src),alt:e.alt??(typeof e.image=="string"?"":e.image.alt||"")}),null,16,rA)):(Y(),fe(xt,{key:1},[Fe(n,ia({class:"dark",image:e.image.dark,alt:e.image.alt},e.$attrs),null,16,["image","alt"]),Fe(n,ia({class:"light",image:e.image.light,alt:e.image.alt},e.$attrs),null,16,["image","alt"])],64))],64)):De("",!0)}}}),wa=Ye(oA,[["__scopeId","data-v-8426fc1a"]]),aA=s=>(Wt("data-v-303bb580"),s=s(),$t(),s),lA={class:"container"},cA={class:"main"},uA={key:0,class:"name"},hA=["innerHTML"],dA=["innerHTML"],fA=["innerHTML"],pA={key:0,class:"actions"},mA={key:0,class:"image"},gA={class:"image-container"},vA=aA(()=>me("div",{class:"image-bg"},null,-1)),_A=Be({__name:"VPHero",props:{name:{},text:{},tagline:{},image:{},actions:{}},setup(s){const e=zr("hero-image-slot-exists");return(t,n)=>(Y(),fe("div",{class:yt(["VPHero",{"has-image":t.image||j(e)}])},[me("div",lA,[me("div",cA,[ue(t.$slots,"home-hero-info-before",{},void 0,!0),ue(t.$slots,"home-hero-info",{},()=>[t.name?(Y(),fe("h1",uA,[me("span",{innerHTML:t.name,class:"clip"},null,8,hA)])):De("",!0),t.text?(Y(),fe("p",{key:1,innerHTML:t.text,class:"text"},null,8,dA)):De("",!0),t.tagline?(Y(),fe("p",{key:2,innerHTML:t.tagline,class:"tagline"},null,8,fA)):De("",!0)],!0),ue(t.$slots,"home-hero-info-after",{},void 0,!0),t.actions?(Y(),fe("div",pA,[(Y(!0),fe(xt,null,Jt(t.actions,i=>(Y(),fe("div",{key:i.link,class:"action"},[Fe(sA,{tag:"a",size:"medium",theme:i.theme,text:i.text,href:i.link,target:i.target,rel:i.rel},null,8,["theme","text","href","target","rel"])]))),128))])):De("",!0),ue(t.$slots,"home-hero-actions-after",{},void 0,!0)]),t.image||j(e)?(Y(),fe("div",mA,[me("div",gA,[vA,ue(t.$slots,"home-hero-image",{},()=>[t.image?(Y(),$e(wa,{key:0,class:"image-src",image:t.image},null,8,["image"])):De("",!0)],!0)])])):De("",!0)])],2))}}),yA=Ye(_A,[["__scopeId","data-v-303bb580"]]),xA=Be({__name:"VPHomeHero",setup(s){const{frontmatter:e}=ot();return(t,n)=>j(e).hero?(Y(),$e(yA,{key:0,class:"VPHomeHero",name:j(e).hero.name,text:j(e).hero.text,tagline:j(e).hero.tagline,image:j(e).hero.image,actions:j(e).hero.actions},{"home-hero-info-before":ye(()=>[ue(t.$slots,"home-hero-info-before")]),"home-hero-info":ye(()=>[ue(t.$slots,"home-hero-info")]),"home-hero-info-after":ye(()=>[ue(t.$slots,"home-hero-info-after")]),"home-hero-actions-after":ye(()=>[ue(t.$slots,"home-hero-actions-after")]),"home-hero-image":ye(()=>[ue(t.$slots,"home-hero-image")]),_:3},8,["name","text","tagline","image","actions"])):De("",!0)}}),MA=s=>(Wt("data-v-a3976bdc"),s=s(),$t(),s),bA={class:"box"},SA={key:0,class:"icon"},wA=["innerHTML"],AA=["innerHTML"],TA=["innerHTML"],EA={key:4,class:"link-text"},CA={class:"link-text-value"},PA=MA(()=>me("span",{class:"vpi-arrow-right link-text-icon"},null,-1)),RA=Be({__name:"VPFeature",props:{icon:{},title:{},details:{},link:{},linkText:{},rel:{},target:{}},setup(s){return(e,t)=>(Y(),$e(Gn,{class:"VPFeature",href:e.link,rel:e.rel,target:e.target,"no-icon":!0,tag:e.link?"a":"div"},{default:ye(()=>[me("article",bA,[typeof e.icon=="object"&&e.icon.wrap?(Y(),fe("div",SA,[Fe(wa,{image:e.icon,alt:e.icon.alt,height:e.icon.height||48,width:e.icon.width||48},null,8,["image","alt","height","width"])])):typeof e.icon=="object"?(Y(),$e(wa,{key:1,image:e.icon,alt:e.icon.alt,height:e.icon.height||48,width:e.icon.width||48},null,8,["image","alt","height","width"])):e.icon?(Y(),fe("div",{key:2,class:"icon",innerHTML:e.icon},null,8,wA)):De("",!0),me("h2",{class:"title",innerHTML:e.title},null,8,AA),e.details?(Y(),fe("p",{key:3,class:"details",innerHTML:e.details},null,8,TA)):De("",!0),e.linkText?(Y(),fe("div",EA,[me("p",CA,[Ht(ft(e.linkText)+" ",1),PA])])):De("",!0)])]),_:1},8,["href","rel","target","tag"]))}}),IA=Ye(RA,[["__scopeId","data-v-a3976bdc"]]),LA={key:0,class:"VPFeatures"},NA={class:"container"},DA={class:"items"},UA=Be({__name:"VPFeatures",props:{features:{}},setup(s){const e=s,t=ke(()=>{const n=e.features.length;if(n){if(n===2)return"grid-2";if(n===3)return"grid-3";if(n%3===0)return"grid-6";if(n>3)return"grid-4"}else return});return(n,i)=>n.features?(Y(),fe("div",LA,[me("div",NA,[me("div",DA,[(Y(!0),fe(xt,null,Jt(n.features,r=>(Y(),fe("div",{key:r.title,class:yt(["item",[t.value]])},[Fe(IA,{icon:r.icon,title:r.title,details:r.details,link:r.link,"link-text":r.linkText,rel:r.rel,target:r.target},null,8,["icon","title","details","link","link-text","rel","target"])],2))),128))])])])):De("",!0)}}),OA=Ye(UA,[["__scopeId","data-v-a6181336"]]),FA=Be({__name:"VPHomeFeatures",setup(s){const{frontmatter:e}=ot();return(t,n)=>j(e).features?(Y(),$e(OA,{key:0,class:"VPHomeFeatures",features:j(e).features},null,8,["features"])):De("",!0)}}),kA=Be({__name:"VPHomeContent",setup(s){const{width:e}=Qm({initialWidth:0,includeScrollbar:!1});return(t,n)=>(Y(),fe("div",{class:"vp-doc container",style:Yc(j(e)?{"--vp-offset":`calc(50% - ${j(e)/2}px)`}:{})},[ue(t.$slots,"default",{},void 0,!0)],4))}}),BA=Ye(kA,[["__scopeId","data-v-8e2d4988"]]),zA={class:"VPHome"},VA=Be({__name:"VPHome",setup(s){const{frontmatter:e}=ot();return(t,n)=>{const i=cn("Content");return Y(),fe("div",zA,[ue(t.$slots,"home-hero-before",{},void 0,!0),Fe(xA,null,{"home-hero-info-before":ye(()=>[ue(t.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":ye(()=>[ue(t.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":ye(()=>[ue(t.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":ye(()=>[ue(t.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":ye(()=>[ue(t.$slots,"home-hero-image",{},void 0,!0)]),_:3}),ue(t.$slots,"home-hero-after",{},void 0,!0),ue(t.$slots,"home-features-before",{},void 0,!0),Fe(FA),ue(t.$slots,"home-features-after",{},void 0,!0),j(e).markdownStyles!==!1?(Y(),$e(BA,{key:0},{default:ye(()=>[Fe(i)]),_:1})):(Y(),$e(i,{key:1}))])}}}),HA=Ye(VA,[["__scopeId","data-v-686f80a6"]]),GA={},WA={class:"VPPage"};function $A(s,e){const t=cn("Content");return Y(),fe("div",WA,[ue(s.$slots,"page-top"),Fe(t),ue(s.$slots,"page-bottom")])}const XA=Ye(GA,[["render",$A]]),qA=Be({__name:"VPContent",setup(s){const{page:e,frontmatter:t}=ot(),{hasSidebar:n}=fi();return(i,r)=>(Y(),fe("div",{class:yt(["VPContent",{"has-sidebar":j(n),"is-home":j(t).layout==="home"}]),id:"VPContent"},[j(e).isNotFound?ue(i.$slots,"not-found",{key:0},()=>[Fe(n1)],!0):j(t).layout==="page"?(Y(),$e(XA,{key:1},{"page-top":ye(()=>[ue(i.$slots,"page-top",{},void 0,!0)]),"page-bottom":ye(()=>[ue(i.$slots,"page-bottom",{},void 0,!0)]),_:3})):j(t).layout==="home"?(Y(),$e(HA,{key:2},{"home-hero-before":ye(()=>[ue(i.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info-before":ye(()=>[ue(i.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":ye(()=>[ue(i.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":ye(()=>[ue(i.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":ye(()=>[ue(i.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":ye(()=>[ue(i.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":ye(()=>[ue(i.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":ye(()=>[ue(i.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":ye(()=>[ue(i.$slots,"home-features-after",{},void 0,!0)]),_:3})):j(t).layout&&j(t).layout!=="doc"?(Y(),$e(Bs(j(t).layout),{key:3})):(Y(),$e(nA,{key:4},{"doc-top":ye(()=>[ue(i.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":ye(()=>[ue(i.$slots,"doc-bottom",{},void 0,!0)]),"doc-footer-before":ye(()=>[ue(i.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":ye(()=>[ue(i.$slots,"doc-before",{},void 0,!0)]),"doc-after":ye(()=>[ue(i.$slots,"doc-after",{},void 0,!0)]),"aside-top":ye(()=>[ue(i.$slots,"aside-top",{},void 0,!0)]),"aside-outline-before":ye(()=>[ue(i.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":ye(()=>[ue(i.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":ye(()=>[ue(i.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":ye(()=>[ue(i.$slots,"aside-ads-after",{},void 0,!0)]),"aside-bottom":ye(()=>[ue(i.$slots,"aside-bottom",{},void 0,!0)]),_:3}))],2))}}),YA=Ye(qA,[["__scopeId","data-v-1428d186"]]),ZA={class:"container"},JA=["innerHTML"],KA=["innerHTML"],jA=Be({__name:"VPFooter",setup(s){const{theme:e,frontmatter:t}=ot(),{hasSidebar:n}=fi();return(i,r)=>j(e).footer&&j(t).footer!==!1?(Y(),fe("footer",{key:0,class:yt(["VPFooter",{"has-sidebar":j(n)}])},[me("div",ZA,[j(e).footer.message?(Y(),fe("p",{key:0,class:"message",innerHTML:j(e).footer.message},null,8,JA)):De("",!0),j(e).footer.copyright?(Y(),fe("p",{key:1,class:"copyright",innerHTML:j(e).footer.copyright},null,8,KA)):De("",!0)])],2)):De("",!0)}}),QA=Ye(jA,[["__scopeId","data-v-e315a0ad"]]);function eT(){const{theme:s,frontmatter:e}=ot(),t=Rn([]),n=ke(()=>t.value.length>0);return Aa(()=>{t.value=Gu(e.value.outline??s.value.outline)}),{headers:t,hasLocalNav:n}}const tT=s=>(Wt("data-v-17a5e62e"),s=s(),$t(),s),nT={class:"menu-text"},iT=tT(()=>me("span",{class:"vpi-chevron-right icon"},null,-1)),sT={class:"header"},rT={class:"outline"},oT=Be({__name:"VPLocalNavOutlineDropdown",props:{headers:{},navHeight:{}},setup(s){const e=s,{theme:t}=ot(),n=Ge(!1),i=Ge(0),r=Ge(),o=Ge();function a(h){var d;(d=r.value)!=null&&d.contains(h.target)||(n.value=!1)}Ct(n,h=>{if(h){document.addEventListener("click",a);return}document.removeEventListener("click",a)}),jl("Escape",()=>{n.value=!1}),Aa(()=>{n.value=!1});function l(){n.value=!n.value,i.value=window.innerHeight+Math.min(window.scrollY-e.navHeight,0)}function c(h){h.target.classList.contains("outline-link")&&(o.value&&(o.value.style.transition="none"),qc(()=>{n.value=!1}))}function u(){n.value=!1,window.scrollTo({top:0,left:0,behavior:"smooth"})}return(h,d)=>(Y(),fe("div",{class:"VPLocalNavOutlineDropdown",style:Yc({"--vp-vh":i.value+"px"}),ref_key:"main",ref:r},[h.headers.length>0?(Y(),fe("button",{key:0,onClick:l,class:yt({open:n.value})},[me("span",nT,ft(j(Tm)(j(t))),1),iT],2)):(Y(),fe("button",{key:1,onClick:u},ft(j(t).returnToTopLabel||"Return to top"),1)),Fe(Zc,{name:"flyout"},{default:ye(()=>[n.value?(Y(),fe("div",{key:0,ref_key:"items",ref:o,class:"items",onClick:c},[me("div",sT,[me("a",{class:"top-link",href:"#",onClick:u},ft(j(t).returnToTopLabel||"Return to top"),1)]),me("div",rT,[Fe(Em,{headers:h.headers},null,8,["headers"])])],512)):De("",!0)]),_:1})],4))}}),aT=Ye(oT,[["__scopeId","data-v-17a5e62e"]]),lT=s=>(Wt("data-v-a6f0e41e"),s=s(),$t(),s),cT={class:"container"},uT=["aria-expanded"],hT=lT(()=>me("span",{class:"vpi-align-left menu-icon"},null,-1)),dT={class:"menu-text"},fT=Be({__name:"VPLocalNav",props:{open:{type:Boolean}},emits:["open-menu"],setup(s){const{theme:e,frontmatter:t}=ot(),{hasSidebar:n}=fi(),{headers:i}=eT(),{y:r}=Zd(),o=Ge(0);Nn(()=>{o.value=parseInt(getComputedStyle(document.documentElement).getPropertyValue("--vp-nav-height"))}),Aa(()=>{i.value=Gu(t.value.outline??e.value.outline)});const a=ke(()=>i.value.length===0),l=ke(()=>a.value&&!n.value),c=ke(()=>({VPLocalNav:!0,"has-sidebar":n.value,empty:a.value,fixed:l.value}));return(u,h)=>j(t).layout!=="home"&&(!l.value||j(r)>=o.value)?(Y(),fe("div",{key:0,class:yt(c.value)},[me("div",cT,[j(n)?(Y(),fe("button",{key:0,class:"menu","aria-expanded":u.open,"aria-controls":"VPSidebarNav",onClick:h[0]||(h[0]=d=>u.$emit("open-menu"))},[hT,me("span",dT,ft(j(e).sidebarMenuLabel||"Menu"),1)],8,uT)):De("",!0),Fe(aT,{headers:j(i),navHeight:o.value},null,8,["headers","navHeight"])])],2)):De("",!0)}}),pT=Ye(fT,[["__scopeId","data-v-a6f0e41e"]]);function mT(){const s=Ge(!1);function e(){s.value=!0,window.addEventListener("resize",i)}function t(){s.value=!1,window.removeEventListener("resize",i)}function n(){s.value?t():e()}function i(){window.outerWidth>=768&&t()}const r=Vr();return Ct(()=>r.path,t),{isScreenOpen:s,openScreen:e,closeScreen:t,toggleScreen:n}}const gT={},vT={class:"VPSwitch",type:"button",role:"switch"},_T={class:"check"},yT={key:0,class:"icon"};function xT(s,e){return Y(),fe("button",vT,[me("span",_T,[s.$slots.default?(Y(),fe("span",yT,[ue(s.$slots,"default",{},void 0,!0)])):De("",!0)])])}const MT=Ye(gT,[["render",xT],["__scopeId","data-v-1d5665e3"]]),Pm=s=>(Wt("data-v-d1f28634"),s=s(),$t(),s),bT=Pm(()=>me("span",{class:"vpi-sun sun"},null,-1)),ST=Pm(()=>me("span",{class:"vpi-moon moon"},null,-1)),wT=Be({__name:"VPSwitchAppearance",setup(s){const{isDark:e,theme:t}=ot(),n=zr("toggle-appearance",()=>{e.value=!e.value}),i=ke(()=>e.value?t.value.lightModeSwitchTitle||"Switch to light theme":t.value.darkModeSwitchTitle||"Switch to dark theme");return(r,o)=>(Y(),$e(MT,{title:i.value,class:"VPSwitchAppearance","aria-checked":j(e),onClick:j(n)},{default:ye(()=>[bT,ST]),_:1},8,["title","aria-checked","onClick"]))}}),Wu=Ye(wT,[["__scopeId","data-v-d1f28634"]]),AT={key:0,class:"VPNavBarAppearance"},TT=Be({__name:"VPNavBarAppearance",setup(s){const{site:e}=ot();return(t,n)=>j(e).appearance&&j(e).appearance!=="force-dark"?(Y(),fe("div",AT,[Fe(Wu)])):De("",!0)}}),ET=Ye(TT,[["__scopeId","data-v-e6aabb21"]]),$u=Ge();let Rm=!1,Jl=0;function CT(s){const e=Ge(!1);if(Ta){!Rm&&PT(),Jl++;const t=Ct($u,n=>{var i,r,o;n===s.el.value||(i=s.el.value)!=null&&i.contains(n)?(e.value=!0,(r=s.onFocus)==null||r.call(s)):(e.value=!1,(o=s.onBlur)==null||o.call(s))});Wn(()=>{t(),Jl--,Jl||RT()})}return gr(e)}function PT(){document.addEventListener("focusin",Im),Rm=!0,$u.value=document.activeElement}function RT(){document.removeEventListener("focusin",Im)}function Im(){$u.value=document.activeElement}const IT={class:"VPMenuLink"},LT=Be({__name:"VPMenuLink",props:{item:{}},setup(s){const{page:e}=ot();return(t,n)=>(Y(),fe("div",IT,[Fe(Gn,{class:yt({active:j(is)(j(e).relativePath,t.item.activeMatch||t.item.link,!!t.item.activeMatch)}),href:t.item.link,target:t.item.target,rel:t.item.rel},{default:ye(()=>[Ht(ft(t.item.text),1)]),_:1},8,["class","href","target","rel"])]))}}),sl=Ye(LT,[["__scopeId","data-v-43f1e123"]]),NT={class:"VPMenuGroup"},DT={key:0,class:"title"},UT=Be({__name:"VPMenuGroup",props:{text:{},items:{}},setup(s){return(e,t)=>(Y(),fe("div",NT,[e.text?(Y(),fe("p",DT,ft(e.text),1)):De("",!0),(Y(!0),fe(xt,null,Jt(e.items,n=>(Y(),fe(xt,null,["link"in n?(Y(),$e(sl,{key:0,item:n},null,8,["item"])):De("",!0)],64))),256))]))}}),OT=Ye(UT,[["__scopeId","data-v-69e747b5"]]),FT={class:"VPMenu"},kT={key:0,class:"items"},BT=Be({__name:"VPMenu",props:{items:{}},setup(s){return(e,t)=>(Y(),fe("div",FT,[e.items?(Y(),fe("div",kT,[(Y(!0),fe(xt,null,Jt(e.items,n=>(Y(),fe(xt,{key:n.text},["link"in n?(Y(),$e(sl,{key:0,item:n},null,8,["item"])):(Y(),$e(OT,{key:1,text:n.text,items:n.items},null,8,["text","items"]))],64))),128))])):De("",!0),ue(e.$slots,"default",{},void 0,!0)]))}}),zT=Ye(BT,[["__scopeId","data-v-e7ea1737"]]),VT=s=>(Wt("data-v-b6c34ac9"),s=s(),$t(),s),HT=["aria-expanded","aria-label"],GT={key:0,class:"text"},WT=["innerHTML"],$T=VT(()=>me("span",{class:"vpi-chevron-down text-icon"},null,-1)),XT={key:1,class:"vpi-more-horizontal icon"},qT={class:"menu"},YT=Be({__name:"VPFlyout",props:{icon:{},button:{},label:{},items:{}},setup(s){const e=Ge(!1),t=Ge();CT({el:t,onBlur:n});function n(){e.value=!1}return(i,r)=>(Y(),fe("div",{class:"VPFlyout",ref_key:"el",ref:t,onMouseenter:r[1]||(r[1]=o=>e.value=!0),onMouseleave:r[2]||(r[2]=o=>e.value=!1)},[me("button",{type:"button",class:"button","aria-haspopup":"true","aria-expanded":e.value,"aria-label":i.label,onClick:r[0]||(r[0]=o=>e.value=!e.value)},[i.button||i.icon?(Y(),fe("span",GT,[i.icon?(Y(),fe("span",{key:0,class:yt([i.icon,"option-icon"])},null,2)):De("",!0),i.button?(Y(),fe("span",{key:1,innerHTML:i.button},null,8,WT)):De("",!0),$T])):(Y(),fe("span",XT))],8,HT),me("div",qT,[Fe(zT,{items:i.items},{default:ye(()=>[ue(i.$slots,"default",{},void 0,!0)]),_:3},8,["items"])])],544))}}),Xu=Ye(YT,[["__scopeId","data-v-b6c34ac9"]]),ZT=["href","aria-label","innerHTML"],JT=Be({__name:"VPSocialLink",props:{icon:{},link:{},ariaLabel:{}},setup(s){const e=s,t=ke(()=>typeof e.icon=="object"?e.icon.svg:``);return(n,i)=>(Y(),fe("a",{class:"VPSocialLink no-icon",href:n.link,"aria-label":n.ariaLabel??(typeof n.icon=="string"?n.icon:""),target:"_blank",rel:"noopener",innerHTML:t.value},null,8,ZT))}}),KT=Ye(JT,[["__scopeId","data-v-eee4e7cb"]]),jT={class:"VPSocialLinks"},QT=Be({__name:"VPSocialLinks",props:{links:{}},setup(s){return(e,t)=>(Y(),fe("div",jT,[(Y(!0),fe(xt,null,Jt(e.links,({link:n,icon:i,ariaLabel:r})=>(Y(),$e(KT,{key:n,icon:i,link:n,ariaLabel:r},null,8,["icon","link","ariaLabel"]))),128))]))}}),qu=Ye(QT,[["__scopeId","data-v-7bc22406"]]),eE={key:0,class:"group translations"},tE={class:"trans-title"},nE={key:1,class:"group"},iE={class:"item appearance"},sE={class:"label"},rE={class:"appearance-action"},oE={key:2,class:"group"},aE={class:"item social-links"},lE=Be({__name:"VPNavBarExtra",setup(s){const{site:e,theme:t}=ot(),{localeLinks:n,currentLang:i}=to({correspondingLink:!0}),r=ke(()=>n.value.length&&i.value.label||e.value.appearance||t.value.socialLinks);return(o,a)=>r.value?(Y(),$e(Xu,{key:0,class:"VPNavBarExtra",label:"extra navigation"},{default:ye(()=>[j(n).length&&j(i).label?(Y(),fe("div",eE,[me("p",tE,ft(j(i).label),1),(Y(!0),fe(xt,null,Jt(j(n),l=>(Y(),$e(sl,{key:l.link,item:l},null,8,["item"]))),128))])):De("",!0),j(e).appearance&&j(e).appearance!=="force-dark"?(Y(),fe("div",nE,[me("div",iE,[me("p",sE,ft(j(t).darkModeSwitchLabel||"Appearance"),1),me("div",rE,[Fe(Wu)])])])):De("",!0),j(t).socialLinks?(Y(),fe("div",oE,[me("div",aE,[Fe(qu,{class:"social-links-list",links:j(t).socialLinks},null,8,["links"])])])):De("",!0)]),_:1})):De("",!0)}}),cE=Ye(lE,[["__scopeId","data-v-d0bd9dde"]]),uE=s=>(Wt("data-v-e5dd9c1c"),s=s(),$t(),s),hE=["aria-expanded"],dE=uE(()=>me("span",{class:"container"},[me("span",{class:"top"}),me("span",{class:"middle"}),me("span",{class:"bottom"})],-1)),fE=[dE],pE=Be({__name:"VPNavBarHamburger",props:{active:{type:Boolean}},emits:["click"],setup(s){return(e,t)=>(Y(),fe("button",{type:"button",class:yt(["VPNavBarHamburger",{active:e.active}]),"aria-label":"mobile navigation","aria-expanded":e.active,"aria-controls":"VPNavScreen",onClick:t[0]||(t[0]=n=>e.$emit("click"))},fE,10,hE))}}),mE=Ye(pE,[["__scopeId","data-v-e5dd9c1c"]]),gE=["innerHTML"],vE=Be({__name:"VPNavBarMenuLink",props:{item:{}},setup(s){const{page:e}=ot();return(t,n)=>(Y(),$e(Gn,{class:yt({VPNavBarMenuLink:!0,active:j(is)(j(e).relativePath,t.item.activeMatch||t.item.link,!!t.item.activeMatch)}),href:t.item.link,noIcon:t.item.noIcon,target:t.item.target,rel:t.item.rel,tabindex:"0"},{default:ye(()=>[me("span",{innerHTML:t.item.text},null,8,gE)]),_:1},8,["class","href","noIcon","target","rel"]))}}),_E=Ye(vE,[["__scopeId","data-v-9c663999"]]),yE=Be({__name:"VPNavBarMenuGroup",props:{item:{}},setup(s){const e=s,{page:t}=ot(),n=r=>"link"in r?is(t.value.relativePath,r.link,!!e.item.activeMatch):r.items.some(n),i=ke(()=>n(e.item));return(r,o)=>(Y(),$e(Xu,{class:yt({VPNavBarMenuGroup:!0,active:j(is)(j(t).relativePath,r.item.activeMatch,!!r.item.activeMatch)||i.value}),button:r.item.text,items:r.item.items},null,8,["class","button","items"]))}}),xE=s=>(Wt("data-v-7f418b0f"),s=s(),$t(),s),ME={key:0,"aria-labelledby":"main-nav-aria-label",class:"VPNavBarMenu"},bE=xE(()=>me("span",{id:"main-nav-aria-label",class:"visually-hidden"},"Main Navigation",-1)),SE=Be({__name:"VPNavBarMenu",setup(s){const{theme:e}=ot();return(t,n)=>j(e).nav?(Y(),fe("nav",ME,[bE,(Y(!0),fe(xt,null,Jt(j(e).nav,i=>(Y(),fe(xt,{key:i.text},["link"in i?(Y(),$e(_E,{key:0,item:i},null,8,["item"])):(Y(),$e(yE,{key:1,item:i},null,8,["item"]))],64))),128))])):De("",!0)}}),wE=Ye(SE,[["__scopeId","data-v-7f418b0f"]]);function AE(s){const{localeIndex:e,theme:t}=ot();function n(i){var g,v,m;const r=i.split("."),o=(g=t.value.search)==null?void 0:g.options,a=o&&typeof o=="object",l=a&&((m=(v=o.locales)==null?void 0:v[e.value])==null?void 0:m.translations)||null,c=a&&o.translations||null;let u=l,h=c,d=s;const f=r.pop();for(const p of r){let y=null;const _=d==null?void 0:d[p];_&&(y=d=_);const x=h==null?void 0:h[p];x&&(y=h=x);const A=u==null?void 0:u[p];A&&(y=u=A),_||(d=y),x||(h=y),A||(u=y)}return(u==null?void 0:u[f])??(h==null?void 0:h[f])??(d==null?void 0:d[f])??""}return n}const TE=["aria-label"],EE={class:"DocSearch-Button-Container"},CE=me("span",{class:"vp-icon DocSearch-Search-Icon"},null,-1),PE={class:"DocSearch-Button-Placeholder"},RE=me("span",{class:"DocSearch-Button-Keys"},[me("kbd",{class:"DocSearch-Button-Key"}),me("kbd",{class:"DocSearch-Button-Key"},"K")],-1),Wd=Be({__name:"VPNavBarSearchButton",setup(s){const t=AE({button:{buttonText:"Search",buttonAriaLabel:"Search"}});return(n,i)=>(Y(),fe("button",{type:"button",class:"DocSearch DocSearch-Button","aria-label":j(t)("button.buttonAriaLabel")},[me("span",EE,[CE,me("span",PE,ft(j(t)("button.buttonText")),1)]),RE],8,TE))}}),IE={class:"VPNavBarSearch"},LE={id:"local-search"},NE={key:1,id:"docsearch"},DE=Be({__name:"VPNavBarSearch",setup(s){const e=eg(()=>tg(()=>import("./VPLocalSearchBox.WgSDvytm.js"),__vite__mapDeps([0,1]))),t=()=>null,{theme:n}=ot(),i=Ge(!1),r=Ge(!1);Nn(()=>{});function o(){i.value||(i.value=!0,setTimeout(a,16))}function a(){const h=new Event("keydown");h.key="k",h.metaKey=!0,window.dispatchEvent(h),setTimeout(()=>{document.querySelector(".DocSearch-Modal")||a()},16)}function l(h){const d=h.target,f=d.tagName;return d.isContentEditable||f==="INPUT"||f==="SELECT"||f==="TEXTAREA"}const c=Ge(!1);jl("k",h=>{(h.ctrlKey||h.metaKey)&&(h.preventDefault(),c.value=!0)}),jl("/",h=>{l(h)||(h.preventDefault(),c.value=!0)});const u="local";return(h,d)=>{var f;return Y(),fe("div",IE,[j(u)==="local"?(Y(),fe(xt,{key:0},[c.value?(Y(),$e(j(e),{key:0,onClose:d[0]||(d[0]=g=>c.value=!1)})):De("",!0),me("div",LE,[Fe(Wd,{onClick:d[1]||(d[1]=g=>c.value=!0)})])],64)):j(u)==="algolia"?(Y(),fe(xt,{key:1},[i.value?(Y(),$e(j(t),{key:0,algolia:((f=j(n).search)==null?void 0:f.options)??j(n).algolia,onVnodeBeforeMount:d[2]||(d[2]=g=>r.value=!0)},null,8,["algolia"])):De("",!0),r.value?De("",!0):(Y(),fe("div",NE,[Fe(Wd,{onClick:o})]))],64)):De("",!0)])}}}),UE=Be({__name:"VPNavBarSocialLinks",setup(s){const{theme:e}=ot();return(t,n)=>j(e).socialLinks?(Y(),$e(qu,{key:0,class:"VPNavBarSocialLinks",links:j(e).socialLinks},null,8,["links"])):De("",!0)}}),OE=Ye(UE,[["__scopeId","data-v-0394ad82"]]),FE=["href","rel","target"],kE={key:1},BE={key:2},zE=Be({__name:"VPNavBarTitle",setup(s){const{site:e,theme:t}=ot(),{hasSidebar:n}=fi(),{currentLang:i}=to(),r=ke(()=>{var l;return typeof t.value.logoLink=="string"?t.value.logoLink:(l=t.value.logoLink)==null?void 0:l.link}),o=ke(()=>{var l;return typeof t.value.logoLink=="string"||(l=t.value.logoLink)==null?void 0:l.rel}),a=ke(()=>{var l;return typeof t.value.logoLink=="string"||(l=t.value.logoLink)==null?void 0:l.target});return(l,c)=>(Y(),fe("div",{class:yt(["VPNavBarTitle",{"has-sidebar":j(n)}])},[me("a",{class:"title",href:r.value??j(Hu)(j(i).link),rel:o.value,target:a.value},[ue(l.$slots,"nav-bar-title-before",{},void 0,!0),j(t).logo?(Y(),$e(wa,{key:0,class:"logo",image:j(t).logo},null,8,["image"])):De("",!0),j(t).siteTitle?(Y(),fe("span",kE,ft(j(t).siteTitle),1)):j(t).siteTitle===void 0?(Y(),fe("span",BE,ft(j(e).title),1)):De("",!0),ue(l.$slots,"nav-bar-title-after",{},void 0,!0)],8,FE)],2))}}),VE=Ye(zE,[["__scopeId","data-v-ab179fa1"]]),HE={class:"items"},GE={class:"title"},WE=Be({__name:"VPNavBarTranslations",setup(s){const{theme:e}=ot(),{localeLinks:t,currentLang:n}=to({correspondingLink:!0});return(i,r)=>j(t).length&&j(n).label?(Y(),$e(Xu,{key:0,class:"VPNavBarTranslations",icon:"vpi-languages",label:j(e).langMenuLabel||"Change language"},{default:ye(()=>[me("div",HE,[me("p",GE,ft(j(n).label),1),(Y(!0),fe(xt,null,Jt(j(t),o=>(Y(),$e(sl,{key:o.link,item:o},null,8,["item"]))),128))])]),_:1},8,["label"])):De("",!0)}}),$E=Ye(WE,[["__scopeId","data-v-88af2de4"]]),XE=s=>(Wt("data-v-ccf7ddec"),s=s(),$t(),s),qE={class:"wrapper"},YE={class:"container"},ZE={class:"title"},JE={class:"content"},KE={class:"content-body"},jE=XE(()=>me("div",{class:"divider"},[me("div",{class:"divider-line"})],-1)),QE=Be({__name:"VPNavBar",props:{isScreenOpen:{type:Boolean}},emits:["toggle-screen"],setup(s){const{y:e}=Zd(),{hasSidebar:t}=fi(),{frontmatter:n}=ot(),i=Ge({});return qd(()=>{i.value={"has-sidebar":t.value,home:n.value.layout==="home",top:e.value===0}}),(r,o)=>(Y(),fe("div",{class:yt(["VPNavBar",i.value])},[me("div",qE,[me("div",YE,[me("div",ZE,[Fe(VE,null,{"nav-bar-title-before":ye(()=>[ue(r.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":ye(()=>[ue(r.$slots,"nav-bar-title-after",{},void 0,!0)]),_:3})]),me("div",JE,[me("div",KE,[ue(r.$slots,"nav-bar-content-before",{},void 0,!0),Fe(DE,{class:"search"}),Fe(wE,{class:"menu"}),Fe($E,{class:"translations"}),Fe(ET,{class:"appearance"}),Fe(OE,{class:"social-links"}),Fe(cE,{class:"extra"}),ue(r.$slots,"nav-bar-content-after",{},void 0,!0),Fe(mE,{class:"hamburger",active:r.isScreenOpen,onClick:o[0]||(o[0]=a=>r.$emit("toggle-screen"))},null,8,["active"])])])])]),jE],2))}}),eC=Ye(QE,[["__scopeId","data-v-ccf7ddec"]]),tC={key:0,class:"VPNavScreenAppearance"},nC={class:"text"},iC=Be({__name:"VPNavScreenAppearance",setup(s){const{site:e,theme:t}=ot();return(n,i)=>j(e).appearance&&j(e).appearance!=="force-dark"?(Y(),fe("div",tC,[me("p",nC,ft(j(t).darkModeSwitchLabel||"Appearance"),1),Fe(Wu)])):De("",!0)}}),sC=Ye(iC,[["__scopeId","data-v-2d7af913"]]),rC=Be({__name:"VPNavScreenMenuLink",props:{item:{}},setup(s){const e=zr("close-screen");return(t,n)=>(Y(),$e(Gn,{class:"VPNavScreenMenuLink",href:t.item.link,target:t.item.target,rel:t.item.rel,onClick:j(e),innerHTML:t.item.text},null,8,["href","target","rel","onClick","innerHTML"]))}}),oC=Ye(rC,[["__scopeId","data-v-7f31e1f6"]]),aC=Be({__name:"VPNavScreenMenuGroupLink",props:{item:{}},setup(s){const e=zr("close-screen");return(t,n)=>(Y(),$e(Gn,{class:"VPNavScreenMenuGroupLink",href:t.item.link,target:t.item.target,rel:t.item.rel,onClick:j(e)},{default:ye(()=>[Ht(ft(t.item.text),1)]),_:1},8,["href","target","rel","onClick"]))}}),Lm=Ye(aC,[["__scopeId","data-v-19976ae1"]]),lC={class:"VPNavScreenMenuGroupSection"},cC={key:0,class:"title"},uC=Be({__name:"VPNavScreenMenuGroupSection",props:{text:{},items:{}},setup(s){return(e,t)=>(Y(),fe("div",lC,[e.text?(Y(),fe("p",cC,ft(e.text),1)):De("",!0),(Y(!0),fe(xt,null,Jt(e.items,n=>(Y(),$e(Lm,{key:n.text,item:n},null,8,["item"]))),128))]))}}),hC=Ye(uC,[["__scopeId","data-v-8133b170"]]),dC=s=>(Wt("data-v-ff6087d4"),s=s(),$t(),s),fC=["aria-controls","aria-expanded"],pC=["innerHTML"],mC=dC(()=>me("span",{class:"vpi-plus button-icon"},null,-1)),gC=["id"],vC={key:1,class:"group"},_C=Be({__name:"VPNavScreenMenuGroup",props:{text:{},items:{}},setup(s){const e=s,t=Ge(!1),n=ke(()=>`NavScreenGroup-${e.text.replace(" ","-").toLowerCase()}`);function i(){t.value=!t.value}return(r,o)=>(Y(),fe("div",{class:yt(["VPNavScreenMenuGroup",{open:t.value}])},[me("button",{class:"button","aria-controls":n.value,"aria-expanded":t.value,onClick:i},[me("span",{class:"button-text",innerHTML:r.text},null,8,pC),mC],8,fC),me("div",{id:n.value,class:"items"},[(Y(!0),fe(xt,null,Jt(r.items,a=>(Y(),fe(xt,{key:a.text},["link"in a?(Y(),fe("div",{key:a.text,class:"item"},[Fe(Lm,{item:a},null,8,["item"])])):(Y(),fe("div",vC,[Fe(hC,{text:a.text,items:a.items},null,8,["text","items"])]))],64))),128))],8,gC)],2))}}),yC=Ye(_C,[["__scopeId","data-v-ff6087d4"]]),xC={key:0,class:"VPNavScreenMenu"},MC=Be({__name:"VPNavScreenMenu",setup(s){const{theme:e}=ot();return(t,n)=>j(e).nav?(Y(),fe("nav",xC,[(Y(!0),fe(xt,null,Jt(j(e).nav,i=>(Y(),fe(xt,{key:i.text},["link"in i?(Y(),$e(oC,{key:0,item:i},null,8,["item"])):(Y(),$e(yC,{key:1,text:i.text||"",items:i.items},null,8,["text","items"]))],64))),128))])):De("",!0)}}),bC=Be({__name:"VPNavScreenSocialLinks",setup(s){const{theme:e}=ot();return(t,n)=>j(e).socialLinks?(Y(),$e(qu,{key:0,class:"VPNavScreenSocialLinks",links:j(e).socialLinks},null,8,["links"])):De("",!0)}}),Nm=s=>(Wt("data-v-858fe1a4"),s=s(),$t(),s),SC=Nm(()=>me("span",{class:"vpi-languages icon lang"},null,-1)),wC=Nm(()=>me("span",{class:"vpi-chevron-down icon chevron"},null,-1)),AC={class:"list"},TC=Be({__name:"VPNavScreenTranslations",setup(s){const{localeLinks:e,currentLang:t}=to({correspondingLink:!0}),n=Ge(!1);function i(){n.value=!n.value}return(r,o)=>j(e).length&&j(t).label?(Y(),fe("div",{key:0,class:yt(["VPNavScreenTranslations",{open:n.value}])},[me("button",{class:"title",onClick:i},[SC,Ht(" "+ft(j(t).label)+" ",1),wC]),me("ul",AC,[(Y(!0),fe(xt,null,Jt(j(e),a=>(Y(),fe("li",{key:a.link,class:"item"},[Fe(Gn,{class:"link",href:a.link},{default:ye(()=>[Ht(ft(a.text),1)]),_:2},1032,["href"])]))),128))])],2)):De("",!0)}}),EC=Ye(TC,[["__scopeId","data-v-858fe1a4"]]),CC={class:"container"},PC=Be({__name:"VPNavScreen",props:{open:{type:Boolean}},setup(s){const e=Ge(null),t=Jd(Ta?document.body:null);return(n,i)=>(Y(),$e(Zc,{name:"fade",onEnter:i[0]||(i[0]=r=>t.value=!0),onAfterLeave:i[1]||(i[1]=r=>t.value=!1)},{default:ye(()=>[n.open?(Y(),fe("div",{key:0,class:"VPNavScreen",ref_key:"screen",ref:e,id:"VPNavScreen"},[me("div",CC,[ue(n.$slots,"nav-screen-content-before",{},void 0,!0),Fe(MC,{class:"menu"}),Fe(EC,{class:"translations"}),Fe(sC,{class:"appearance"}),Fe(bC,{class:"social-links"}),ue(n.$slots,"nav-screen-content-after",{},void 0,!0)])],512)):De("",!0)]),_:3}))}}),RC=Ye(PC,[["__scopeId","data-v-cc5739dd"]]),IC={key:0,class:"VPNav"},LC=Be({__name:"VPNav",setup(s){const{isScreenOpen:e,closeScreen:t,toggleScreen:n}=mT(),{frontmatter:i}=ot(),r=ke(()=>i.value.navbar!==!1);return vr("close-screen",t),Ri(()=>{Ta&&document.documentElement.classList.toggle("hide-nav",!r.value)}),(o,a)=>r.value?(Y(),fe("header",IC,[Fe(eC,{"is-screen-open":j(e),onToggleScreen:j(n)},{"nav-bar-title-before":ye(()=>[ue(o.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":ye(()=>[ue(o.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":ye(()=>[ue(o.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":ye(()=>[ue(o.$slots,"nav-bar-content-after",{},void 0,!0)]),_:3},8,["is-screen-open","onToggleScreen"]),Fe(RC,{open:j(e)},{"nav-screen-content-before":ye(()=>[ue(o.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":ye(()=>[ue(o.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3},8,["open"])])):De("",!0)}}),NC=Ye(LC,[["__scopeId","data-v-ae24b3ad"]]),Dm=s=>(Wt("data-v-b8d55f3b"),s=s(),$t(),s),DC=["role","tabindex"],UC=Dm(()=>me("div",{class:"indicator"},null,-1)),OC=["onKeydown"],FC=Dm(()=>me("span",{class:"vpi-chevron-right caret-icon"},null,-1)),kC=[FC],BC={key:1,class:"items"},zC=Be({__name:"VPSidebarItem",props:{item:{},depth:{}},setup(s){const e=s,{collapsed:t,collapsible:n,isLink:i,isActiveLink:r,hasActiveLink:o,hasChildren:a,toggle:l}=o1(ke(()=>e.item)),c=ke(()=>a.value?"section":"div"),u=ke(()=>i.value?"a":"div"),h=ke(()=>a.value?e.depth+2===7?"p":`h${e.depth+2}`:"p"),d=ke(()=>i.value?void 0:"button"),f=ke(()=>[[`level-${e.depth}`],{collapsible:n.value},{collapsed:t.value},{"is-link":i.value},{"is-active":r.value},{"has-active":o.value}]);function g(m){"key"in m&&m.key!=="Enter"||!e.item.link&&l()}function v(){e.item.link&&l()}return(m,p)=>{const y=cn("VPSidebarItem",!0);return Y(),$e(Bs(c.value),{class:yt(["VPSidebarItem",f.value])},{default:ye(()=>[m.item.text?(Y(),fe("div",ia({key:0,class:"item",role:d.value},ng(m.item.items?{click:g,keydown:g}:{},!0),{tabindex:m.item.items&&0}),[UC,m.item.link?(Y(),$e(Gn,{key:0,tag:u.value,class:"link",href:m.item.link,rel:m.item.rel,target:m.item.target},{default:ye(()=>[(Y(),$e(Bs(h.value),{class:"text",innerHTML:m.item.text},null,8,["innerHTML"]))]),_:1},8,["tag","href","rel","target"])):(Y(),$e(Bs(h.value),{key:1,class:"text",innerHTML:m.item.text},null,8,["innerHTML"])),m.item.collapsed!=null&&m.item.items&&m.item.items.length?(Y(),fe("div",{key:2,class:"caret",role:"button","aria-label":"toggle section",onClick:v,onKeydown:ig(v,["enter"]),tabindex:"0"},kC,40,OC)):De("",!0)],16,DC)):De("",!0),m.item.items&&m.item.items.length?(Y(),fe("div",BC,[m.depth<5?(Y(!0),fe(xt,{key:0},Jt(m.item.items,_=>(Y(),$e(y,{key:_.text,item:_,depth:m.depth+1},null,8,["item","depth"]))),128)):De("",!0)])):De("",!0)]),_:1},8,["class"])}}}),VC=Ye(zC,[["__scopeId","data-v-b8d55f3b"]]),Um=s=>(Wt("data-v-575e6a36"),s=s(),$t(),s),HC=Um(()=>me("div",{class:"curtain"},null,-1)),GC={class:"nav",id:"VPSidebarNav","aria-labelledby":"sidebar-aria-label",tabindex:"-1"},WC=Um(()=>me("span",{class:"visually-hidden",id:"sidebar-aria-label"}," Sidebar Navigation ",-1)),$C=Be({__name:"VPSidebar",props:{open:{type:Boolean}},setup(s){const e=s,{sidebarGroups:t,hasSidebar:n}=fi(),i=Ge(null),r=Jd(Ta?document.body:null);return Ct([e,i],()=>{var o;e.open?(r.value=!0,(o=i.value)==null||o.focus()):r.value=!1},{immediate:!0,flush:"post"}),(o,a)=>j(n)?(Y(),fe("aside",{key:0,class:yt(["VPSidebar",{open:o.open}]),ref_key:"navEl",ref:i,onClick:a[0]||(a[0]=sg(()=>{},["stop"]))},[HC,me("nav",GC,[WC,ue(o.$slots,"sidebar-nav-before",{},void 0,!0),(Y(!0),fe(xt,null,Jt(j(t),l=>(Y(),fe("div",{key:l.text,class:"group"},[Fe(VC,{item:l,depth:0},null,8,["item"])]))),128)),ue(o.$slots,"sidebar-nav-after",{},void 0,!0)])],2)):De("",!0)}}),XC=Ye($C,[["__scopeId","data-v-575e6a36"]]),qC=Be({__name:"VPSkipLink",setup(s){const e=Vr(),t=Ge();Ct(()=>e.path,()=>t.value.focus());function n({target:i}){const r=document.getElementById(decodeURIComponent(i.hash).slice(1));if(r){const o=()=>{r.removeAttribute("tabindex"),r.removeEventListener("blur",o)};r.setAttribute("tabindex","-1"),r.addEventListener("blur",o),r.focus(),window.scrollTo(0,0)}}return(i,r)=>(Y(),fe(xt,null,[me("span",{ref_key:"backToTop",ref:t,tabindex:"-1"},null,512),me("a",{href:"#VPContent",class:"VPSkipLink visually-hidden",onClick:n}," Skip to content ")],64))}}),YC=Ye(qC,[["__scopeId","data-v-0f60ec36"]]),ZC=Be({__name:"Layout",setup(s){const{isOpen:e,open:t,close:n}=fi(),i=Vr();Ct(()=>i.path,n),r1(e,n);const{frontmatter:r}=ot(),o=Xd(),a=ke(()=>!!o["home-hero-image"]);return vr("hero-image-slot-exists",a),(l,c)=>{const u=cn("Content");return j(r).layout!==!1?(Y(),fe("div",{key:0,class:yt(["Layout",j(r).pageClass])},[ue(l.$slots,"layout-top",{},void 0,!0),Fe(YC),Fe(Ww,{class:"backdrop",show:j(e),onClick:j(n)},null,8,["show","onClick"]),Fe(NC,null,{"nav-bar-title-before":ye(()=>[ue(l.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":ye(()=>[ue(l.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":ye(()=>[ue(l.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":ye(()=>[ue(l.$slots,"nav-bar-content-after",{},void 0,!0)]),"nav-screen-content-before":ye(()=>[ue(l.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":ye(()=>[ue(l.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3}),Fe(pT,{open:j(e),onOpenMenu:j(t)},null,8,["open","onOpenMenu"]),Fe(XC,{open:j(e)},{"sidebar-nav-before":ye(()=>[ue(l.$slots,"sidebar-nav-before",{},void 0,!0)]),"sidebar-nav-after":ye(()=>[ue(l.$slots,"sidebar-nav-after",{},void 0,!0)]),_:3},8,["open"]),Fe(YA,null,{"page-top":ye(()=>[ue(l.$slots,"page-top",{},void 0,!0)]),"page-bottom":ye(()=>[ue(l.$slots,"page-bottom",{},void 0,!0)]),"not-found":ye(()=>[ue(l.$slots,"not-found",{},void 0,!0)]),"home-hero-before":ye(()=>[ue(l.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info-before":ye(()=>[ue(l.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":ye(()=>[ue(l.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":ye(()=>[ue(l.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":ye(()=>[ue(l.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":ye(()=>[ue(l.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":ye(()=>[ue(l.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":ye(()=>[ue(l.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":ye(()=>[ue(l.$slots,"home-features-after",{},void 0,!0)]),"doc-footer-before":ye(()=>[ue(l.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":ye(()=>[ue(l.$slots,"doc-before",{},void 0,!0)]),"doc-after":ye(()=>[ue(l.$slots,"doc-after",{},void 0,!0)]),"doc-top":ye(()=>[ue(l.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":ye(()=>[ue(l.$slots,"doc-bottom",{},void 0,!0)]),"aside-top":ye(()=>[ue(l.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":ye(()=>[ue(l.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":ye(()=>[ue(l.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":ye(()=>[ue(l.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":ye(()=>[ue(l.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":ye(()=>[ue(l.$slots,"aside-ads-after",{},void 0,!0)]),_:3}),Fe(QA),ue(l.$slots,"layout-bottom",{},void 0,!0)],2)):(Y(),$e(u,{key:1}))}}}),JC=Ye(ZC,[["__scopeId","data-v-5d98c3a5"]]),Om={Layout:JC,enhanceApp:({app:s})=>{s.component("Badge",Vw)}},KC=Be({__name:"HighlightTargetedHeading",setup(s){function e(){if(!window||!window.location||!window.location.hash)return;const n=decodeURIComponent(window.location.hash);if(!n)return;let i;try{i=document.querySelector(n)}catch(r){console.error(r);return}i&&(i.classList.contains("VPNolebaseHighlightTargetedHeading")||i.classList.add("VPNolebaseHighlightTargetedHeading"),i.classList.remove("VPNolebaseHighlightTargetedHeadingAnimated"),setTimeout(()=>{i&&i.classList.add("VPNolebaseHighlightTargetedHeadingAnimated")},10))}const t=Vr();return Nn(e),Ct(t,async()=>{await qc(),e()}),rg("hashchange",e),(n,i)=>ue(n.$slots,"default")}}),no=s=>(Wt("data-v-ebc087d8"),s=s(),$t(),s),jC={class:"background"},QC={class:"vp-doc"},eP=no(()=>me("a",{class:"h-card",rel:"me",href:"/about"},[me("img",{src:ag,alt:""}),Ht("The Paper Pilot")],-1)),tP=no(()=>me("a",{rel:"license",href:"https://creativecommons.org/licenses/by-nc-sa/4.0/"},"CC BY-NC-SA 4.0",-1)),nP=no(()=>me("div",null,"Any and all opinions listed here are my own and not representative of my employers; future, past and present.",-1)),iP=no(()=>me("div",null,[me("a",{href:"https://resume.incremental.social/thepaperpilot/thepaperpilot"},"Resume"),Ht(" (not actively seeking new opportunities).")],-1)),sP=no(()=>me("div",null,[Ht("Site built from "),me("a",{href:"https://code.incremental.social/thepaperpilot/pages/commit/9aa6bf46bfd132527bed478007a37223f4f29de6"},"this commit"),Ht(" on "),me("time",null,"Thursday, November 28, 2024 at 22:01:32"),Ht(". "),me("a",{href:"https://www.thepaperpilot.org/licenses.txt"},"Legal disclaimers"),Ht(".")],-1)),rP=Be({__name:"Layout",setup(s){return(e,t)=>{const n=cn("TresOrthographicCamera"),i=cn("TresAmbientLight"),r=cn("ClientOnly");return Y(),$e(j(Om).Layout,null,{"layout-top":ye(()=>[Fe(j(KC)),Fe(r,null,{default:ye(()=>[me("div",jC,[Fe(j(Ow),null,{default:ye(()=>[Fe(n,{position:[0,0,10]}),Fe(i,{intensity:1}),(Y(),$e(og,null,{default:ye(()=>[Fe(zw)]),_:1}))]),_:1})])]),_:1})]),"layout-bottom":ye(()=>[me("footer",QC,[me("div",null,[Ht("CC "+ft(new Date().getFullYear())+" ",1),eP,Ht(". "),tP,Ht(".")]),nP,iP,sP])]),_:1})}}}),oP=Ye(rP,[["__scopeId","data-v-ebc087d8"]]),lP={...Om,Layout:oP};export{Pc as A,Bn as K,es as N,xg as R,N as V,zw as _,lP as a,AE as c,kw as n,xw as r,Ow as t,ot as u}; +`;return(p,y)=>{const _=cn("TresShapeGeometry"),x=cn("TresShaderMaterial"),A=cn("TresMesh"),b=cn("TresGroup");return j(i)?(Y(),$e(b,{key:0,ref_key:"groupRef",ref:g,renderOrder:1},{default:ye(()=>[(Y(!0),fe(xt,null,Jt(l.value*c.value,E=>(Y(),$e(A,{position:[(E%c.value-c.value/2)*304,(Math.floor((E-1)/c.value)-l.value/2)*304,1]},{default:ye(()=>[Fe(_,{args:[j(a)]},null,8,["args"]),Fe(x,{vertexShader:Bw,fragmentShader:m,uniforms:v,blending:j(ga),stencilWrite:p.mask!=null,stencilRef:p.mask??0,stencilFunc:j(Zf),stencilFail:j(Bn),stencilZFail:j(Bn),stencilZPass:j(Bn)},null,8,["blending","stencilWrite","stencilRef","stencilFunc","stencilFail","stencilZFail","stencilZPass"])]),_:2},1032,["position"]))),256))]),_:1},512)):De("",!0)}}}),Vw=Be({__name:"VPBadge",props:{text:{},type:{default:"tip"}},setup(s){return(e,t)=>(Y(),fe("span",{class:yt(["VPBadge",e.type])},[ue(e.$slots,"default",{},()=>[Ht(ft(e.text),1)])],2))}}),Hw={key:0,class:"VPBackdrop"},Gw=Be({__name:"VPBackdrop",props:{show:{type:Boolean}},setup(s){return(e,t)=>(Y(),$e(Zc,{name:"fade"},{default:ye(()=>[e.show?(Y(),fe("div",Hw)):De("",!0)]),_:1}))}}),Ww=Ye(Gw,[["__scopeId","data-v-c79a1216"]]),ot=Ym;function $w(s,e){let t,n=!1;return()=>{t&&clearTimeout(t),n?t=setTimeout(s,e):(s(),(n=!0)&&setTimeout(()=>n=!1,e))}}function Wc(s){return/^\//.test(s)?s:`/${s}`}function Hu(s){const{pathname:e,search:t,hash:n,protocol:i}=new URL(s,"http://a.com");if(Zm(s)||s.startsWith("#")||!i.startsWith("http")||!Jm(e))return s;const{site:r}=ot(),o=e.endsWith("/")||e.endsWith(".html")?s:s.replace(/(?:(^\.+)\/)?.*$/,`$1${e.replace(/(\.md)?$/,r.value.cleanUrls?"":".html")}${t}${n}`);return Jc(o)}function to({correspondingLink:s=!1}={}){const{site:e,localeIndex:t,page:n,theme:i,hash:r}=ot(),o=ke(()=>{var l,c;return{label:(l=e.value.locales[t.value])==null?void 0:l.label,link:((c=e.value.locales[t.value])==null?void 0:c.link)||(t.value==="root"?"/":`/${t.value}/`)}});return{localeLinks:ke(()=>Object.entries(e.value.locales).flatMap(([l,c])=>o.value.label===c.label?[]:{text:c.label,link:Xw(c.link||(l==="root"?"/":`/${l}/`),i.value.i18nRouting!==!1&&s,n.value.relativePath.slice(o.value.link.length-1),!e.value.cleanUrls)+r.value})),currentLang:o}}function Xw(s,e,t,n){return e?s.replace(/\/$/,"")+Wc(t.replace(/(^|\/)index\.md$/,"$1").replace(/\.md$/,n?".html":"")):s}const qw=s=>(Wt("data-v-d6be1790"),s=s(),$t(),s),Yw={class:"NotFound"},Zw={class:"code"},Jw={class:"title"},Kw=qw(()=>me("div",{class:"divider"},null,-1)),jw={class:"quote"},Qw={class:"action"},e1=["href","aria-label"],t1=Be({__name:"NotFound",setup(s){const{theme:e}=ot(),{currentLang:t}=to();return(n,i)=>{var r,o,a,l,c;return Y(),fe("div",Yw,[me("p",Zw,ft(((r=j(e).notFound)==null?void 0:r.code)??"404"),1),me("h1",Jw,ft(((o=j(e).notFound)==null?void 0:o.title)??"PAGE NOT FOUND"),1),Kw,me("blockquote",jw,ft(((a=j(e).notFound)==null?void 0:a.quote)??"But if you don't change your direction, and if you keep looking, you may end up where you are heading."),1),me("div",Qw,[me("a",{class:"link",href:j(Jc)(j(t).link),"aria-label":((l=j(e).notFound)==null?void 0:l.linkLabel)??"go to home"},ft(((c=j(e).notFound)==null?void 0:c.linkText)??"Take me home"),9,e1)])])}}}),n1=Ye(t1,[["__scopeId","data-v-d6be1790"]]);function Am(s,e){if(Array.isArray(s))return pa(s);if(s==null)return[];e=Wc(e);const t=Object.keys(s).sort((i,r)=>r.split("/").length-i.split("/").length).find(i=>e.startsWith(Wc(i))),n=t?s[t]:[];return Array.isArray(n)?pa(n):pa(n.items,n.base)}function i1(s){const e=[];let t=0;for(const n in s){const i=s[n];if(i.items){t=e.push(i);continue}e[t]||e.push({items:[]}),e[t].items.push(i)}return e}function s1(s){const e=[];function t(n){for(const i of n)i.text&&i.link&&e.push({text:i.text,link:i.link,docFooterText:i.docFooterText}),i.items&&t(i.items)}return t(s),e}function $c(s,e){return Array.isArray(e)?e.some(t=>$c(s,t)):is(s,e.link)?!0:e.items?$c(s,e.items):!1}function pa(s,e){return[...s].map(t=>{const n={...t},i=n.base||e;return i&&n.link&&(n.link=i+n.link),n.items&&(n.items=pa(n.items,i)),n})}function fi(){const{frontmatter:s,page:e,theme:t}=ot(),n=Kl("(min-width: 960px)"),i=Ge(!1),r=ke(()=>{const v=t.value.sidebar,m=e.value.relativePath;return v?Am(v,m):[]}),o=Ge(r.value);Ct(r,(v,m)=>{JSON.stringify(v)!==JSON.stringify(m)&&(o.value=r.value)});const a=ke(()=>s.value.sidebar!==!1&&o.value.length>0&&s.value.layout!=="home"),l=ke(()=>c?s.value.aside==null?t.value.aside==="left":s.value.aside==="left":!1),c=ke(()=>s.value.layout==="home"?!1:s.value.aside!=null?!!s.value.aside:t.value.aside!==!1),u=ke(()=>a.value&&n.value),h=ke(()=>a.value?i1(o.value):[]);function d(){i.value=!0}function f(){i.value=!1}function g(){i.value?f():d()}return{isOpen:i,sidebar:o,sidebarGroups:h,hasSidebar:a,hasAside:c,leftAside:l,isSidebarEnabled:u,open:d,close:f,toggle:g}}function r1(s,e){let t;Ri(()=>{t=s.value?document.activeElement:void 0}),Nn(()=>{window.addEventListener("keyup",n)}),Wn(()=>{window.removeEventListener("keyup",n)});function n(i){i.key==="Escape"&&s.value&&(e(),t==null||t.focus())}}function o1(s){const{page:e,hash:t}=ot(),n=Ge(!1),i=ke(()=>s.value.collapsed!=null),r=ke(()=>!!s.value.link),o=Ge(!1),a=()=>{o.value=is(e.value.relativePath,s.value.link)};Ct([e,s,t],a),Nn(a);const l=ke(()=>o.value?!0:s.value.items?$c(e.value.relativePath,s.value.items):!1),c=ke(()=>!!(s.value.items&&s.value.items.length));Ri(()=>{n.value=!!(i.value&&s.value.collapsed)}),qd(()=>{(o.value||l.value)&&(n.value=!1)});function u(){i.value&&(n.value=!n.value)}return{collapsed:n,collapsible:i,isLink:r,isActiveLink:o,hasActiveLink:l,hasChildren:c,toggle:u}}function a1(){const{hasSidebar:s}=fi(),e=Kl("(min-width: 960px)"),t=Kl("(min-width: 1280px)");return{isAsideEnabled:ke(()=>!t.value&&!e.value?!1:s.value?t.value:e.value)}}const Xc=[];function Tm(s){return typeof s.outline=="object"&&!Array.isArray(s.outline)&&s.outline.label||s.outlineTitle||"On this page"}function Gu(s){const e=[...document.querySelectorAll(".VPDoc :where(h1,h2,h3,h4,h5,h6)")].filter(t=>t.id&&t.hasChildNodes()).map(t=>{const n=Number(t.tagName[1]);return{element:t,title:l1(t),link:"#"+t.id,level:n}});return c1(e,s)}function l1(s){let e="";for(const t of s.childNodes)if(t.nodeType===1){if(t.classList.contains("VPBadge")||t.classList.contains("header-anchor")||t.classList.contains("ignore-header"))continue;e+=t.textContent}else t.nodeType===3&&(e+=t.textContent);return e.trim()}function c1(s,e){if(e===!1)return[];const t=(typeof e=="object"&&!Array.isArray(e)?e.level:e)||2,[n,i]=typeof t=="number"?[t,t]:t==="deep"?[2,6]:t;s=s.filter(o=>o.level>=n&&o.level<=i),Xc.length=0;for(const{element:o,link:a}of s)Xc.push({element:o,link:a});const r=[];e:for(let o=0;o=0;l--){const c=s[l];if(c.level{requestAnimationFrame(r),window.addEventListener("scroll",n)}),Km(()=>{o(location.hash)}),Wn(()=>{window.removeEventListener("scroll",n)});function r(){if(!t.value)return;const a=window.scrollY,l=window.innerHeight,c=document.body.offsetHeight,u=Math.abs(a+l-c)<1,h=Xc.map(({element:f,link:g})=>({link:g,top:h1(f)})).filter(({top:f})=>!Number.isNaN(f)).sort((f,g)=>f.top-g.top);if(!h.length){o(null);return}if(a<1){o(null);return}if(u){o(h[h.length-1].link);return}let d=null;for(const{link:f,top:g}of h){if(g>a+jm()+4)break;d=f}o(d)}function o(a){i&&i.classList.remove("active"),a==null?i=null:i=s.value.querySelector(`a[href="${decodeURIComponent(a)}"]`);const l=i;l?(l.classList.add("active"),e.value.style.top=l.offsetTop+39+"px",e.value.style.opacity="1"):(e.value.style.top="33px",e.value.style.opacity="0")}}function h1(s){let e=0;for(;s!==document.body;){if(s===null)return NaN;e+=s.offsetTop,s=s.offsetParent}return e}const d1=["href","title"],f1=Be({__name:"VPDocOutlineItem",props:{headers:{},root:{type:Boolean}},setup(s){function e({target:t}){const n=t.href.split("#")[1],i=document.getElementById(decodeURIComponent(n));i==null||i.focus({preventScroll:!0})}return(t,n)=>{const i=cn("VPDocOutlineItem",!0);return Y(),fe("ul",{class:yt(["VPDocOutlineItem",t.root?"root":"nested"])},[(Y(!0),fe(xt,null,Jt(t.headers,({children:r,link:o,title:a})=>(Y(),fe("li",null,[me("a",{class:"outline-link",href:o,onClick:e,title:a},ft(a),9,d1),r!=null&&r.length?(Y(),$e(i,{key:0,headers:r},null,8,["headers"])):De("",!0)]))),256))],2)}}}),Em=Ye(f1,[["__scopeId","data-v-b933a997"]]),p1={class:"content"},m1={"aria-level":"2",class:"outline-title",id:"doc-outline-aria-label",role:"heading"},g1=Be({__name:"VPDocAsideOutline",setup(s){const{frontmatter:e,theme:t}=ot(),n=Rn([]);Aa(()=>{n.value=Gu(e.value.outline??t.value.outline)});const i=Ge(),r=Ge();return u1(i,r),(o,a)=>(Y(),fe("nav",{"aria-labelledby":"doc-outline-aria-label",class:yt(["VPDocAsideOutline",{"has-outline":n.value.length>0}]),ref_key:"container",ref:i},[me("div",p1,[me("div",{class:"outline-marker",ref_key:"marker",ref:r},null,512),me("div",m1,ft(j(Tm)(j(t))),1),Fe(Em,{headers:n.value,root:!0},null,8,["headers"])])],2))}}),v1=Ye(g1,[["__scopeId","data-v-a5bbad30"]]),_1={class:"VPDocAsideCarbonAds"},y1=Be({__name:"VPDocAsideCarbonAds",props:{carbonAds:{}},setup(s){const e=()=>null;return(t,n)=>(Y(),fe("div",_1,[Fe(j(e),{"carbon-ads":t.carbonAds},null,8,["carbon-ads"])]))}}),x1=s=>(Wt("data-v-3f215769"),s=s(),$t(),s),M1={class:"VPDocAside"},b1=x1(()=>me("div",{class:"spacer"},null,-1)),S1=Be({__name:"VPDocAside",setup(s){const{theme:e}=ot();return(t,n)=>(Y(),fe("div",M1,[ue(t.$slots,"aside-top",{},void 0,!0),ue(t.$slots,"aside-outline-before",{},void 0,!0),Fe(v1),ue(t.$slots,"aside-outline-after",{},void 0,!0),b1,ue(t.$slots,"aside-ads-before",{},void 0,!0),j(e).carbonAds?(Y(),$e(y1,{key:0,"carbon-ads":j(e).carbonAds},null,8,["carbon-ads"])):De("",!0),ue(t.$slots,"aside-ads-after",{},void 0,!0),ue(t.$slots,"aside-bottom",{},void 0,!0)]))}}),w1=Ye(S1,[["__scopeId","data-v-3f215769"]]);function A1(){const{theme:s,page:e}=ot();return ke(()=>{const{text:t="Edit this page",pattern:n=""}=s.value.editLink||{};let i;return typeof n=="function"?i=n(e.value):i=n.replace(/:path/g,e.value.filePath),{url:i,text:t}})}function T1(){const{page:s,theme:e,frontmatter:t}=ot();return ke(()=>{var c,u,h,d,f,g,v,m;const n=Am(e.value.sidebar,s.value.relativePath),i=s1(n),r=E1(i,p=>p.link.replace(/[?#].*$/,"")),o=r.findIndex(p=>is(s.value.relativePath,p.link)),a=((c=e.value.docFooter)==null?void 0:c.prev)===!1&&!t.value.prev||t.value.prev===!1,l=((u=e.value.docFooter)==null?void 0:u.next)===!1&&!t.value.next||t.value.next===!1;return{prev:a?void 0:{text:(typeof t.value.prev=="string"?t.value.prev:typeof t.value.prev=="object"?t.value.prev.text:void 0)??((h=r[o-1])==null?void 0:h.docFooterText)??((d=r[o-1])==null?void 0:d.text),link:(typeof t.value.prev=="object"?t.value.prev.link:void 0)??((f=r[o-1])==null?void 0:f.link)},next:l?void 0:{text:(typeof t.value.next=="string"?t.value.next:typeof t.value.next=="object"?t.value.next.text:void 0)??((g=r[o+1])==null?void 0:g.docFooterText)??((v=r[o+1])==null?void 0:v.text),link:(typeof t.value.next=="object"?t.value.next.link:void 0)??((m=r[o+1])==null?void 0:m.link)}}})}function E1(s,e){const t=new Set;return s.filter(n=>{const i=e(n);return t.has(i)?!1:t.add(i)})}const Gn=Be({__name:"VPLink",props:{tag:{},href:{},noIcon:{type:Boolean},target:{},rel:{}},setup(s){const e=s,t=ke(()=>e.tag??(e.href?"a":"span")),n=ke(()=>e.href&&Yd.test(e.href)||e.target==="_blank");return(i,r)=>(Y(),$e(Bs(t.value),{class:yt(["VPLink",{link:i.href,"vp-external-link-icon":n.value,"no-icon":i.noIcon}]),href:i.href?j(Hu)(i.href):void 0,target:i.target??(n.value?"_blank":void 0),rel:i.rel??(n.value?"noreferrer":void 0)},{default:ye(()=>[ue(i.$slots,"default")]),_:3},8,["class","href","target","rel"]))}}),C1={class:"VPLastUpdated"},P1=["datetime"],R1=Be({__name:"VPDocFooterLastUpdated",setup(s){const{theme:e,page:t,frontmatter:n,lang:i}=ot(),r=ke(()=>new Date(n.value.lastUpdated??t.value.lastUpdated)),o=ke(()=>r.value.toISOString()),a=Ge("");return Nn(()=>{Ri(()=>{var l,c,u;a.value=new Intl.DateTimeFormat((c=(l=e.value.lastUpdated)==null?void 0:l.formatOptions)!=null&&c.forceLocale?i.value:void 0,((u=e.value.lastUpdated)==null?void 0:u.formatOptions)??{dateStyle:"short",timeStyle:"short"}).format(r.value)})}),(l,c)=>{var u;return Y(),fe("p",C1,[Ht(ft(((u=j(e).lastUpdated)==null?void 0:u.text)||j(e).lastUpdatedText||"Last updated")+": ",1),me("time",{datetime:o.value},ft(a.value),9,P1)])}}}),I1=Ye(R1,[["__scopeId","data-v-7e05ebdb"]]),Cm=s=>(Wt("data-v-d4a0bba5"),s=s(),$t(),s),L1={key:0,class:"VPDocFooter"},N1={key:0,class:"edit-info"},D1={key:0,class:"edit-link"},U1=Cm(()=>me("span",{class:"vpi-square-pen edit-link-icon"},null,-1)),O1={key:1,class:"last-updated"},F1={key:1,class:"prev-next","aria-labelledby":"doc-footer-aria-label"},k1=Cm(()=>me("span",{class:"visually-hidden",id:"doc-footer-aria-label"},"Pager",-1)),B1={class:"pager"},z1=["innerHTML"],V1=["innerHTML"],H1={class:"pager"},G1=["innerHTML"],W1=["innerHTML"],$1=Be({__name:"VPDocFooter",setup(s){const{theme:e,page:t,frontmatter:n}=ot(),i=A1(),r=T1(),o=ke(()=>e.value.editLink&&n.value.editLink!==!1),a=ke(()=>t.value.lastUpdated&&n.value.lastUpdated!==!1),l=ke(()=>o.value||a.value||r.value.prev||r.value.next);return(c,u)=>{var h,d,f,g;return l.value?(Y(),fe("footer",L1,[ue(c.$slots,"doc-footer-before",{},void 0,!0),o.value||a.value?(Y(),fe("div",N1,[o.value?(Y(),fe("div",D1,[Fe(Gn,{class:"edit-link-button",href:j(i).url,"no-icon":!0},{default:ye(()=>[U1,Ht(" "+ft(j(i).text),1)]),_:1},8,["href"])])):De("",!0),a.value?(Y(),fe("div",O1,[Fe(I1)])):De("",!0)])):De("",!0),(h=j(r).prev)!=null&&h.link||(d=j(r).next)!=null&&d.link?(Y(),fe("nav",F1,[k1,me("div",B1,[(f=j(r).prev)!=null&&f.link?(Y(),$e(Gn,{key:0,class:"pager-link prev",href:j(r).prev.link},{default:ye(()=>{var v;return[me("span",{class:"desc",innerHTML:((v=j(e).docFooter)==null?void 0:v.prev)||"Previous page"},null,8,z1),me("span",{class:"title",innerHTML:j(r).prev.text},null,8,V1)]}),_:1},8,["href"])):De("",!0)]),me("div",H1,[(g=j(r).next)!=null&&g.link?(Y(),$e(Gn,{key:0,class:"pager-link next",href:j(r).next.link},{default:ye(()=>{var v;return[me("span",{class:"desc",innerHTML:((v=j(e).docFooter)==null?void 0:v.next)||"Next page"},null,8,G1),me("span",{class:"title",innerHTML:j(r).next.text},null,8,W1)]}),_:1},8,["href"])):De("",!0)])])):De("",!0)])):De("",!0)}}}),X1=Ye($1,[["__scopeId","data-v-d4a0bba5"]]),q1=s=>(Wt("data-v-39a288b8"),s=s(),$t(),s),Y1={class:"container"},Z1=q1(()=>me("div",{class:"aside-curtain"},null,-1)),J1={class:"aside-container"},K1={class:"aside-content"},j1={class:"content"},Q1={class:"content-container"},eA={class:"main"},tA=Be({__name:"VPDoc",setup(s){const{theme:e}=ot(),t=Vr(),{hasSidebar:n,hasAside:i,leftAside:r}=fi(),o=ke(()=>t.path.replace(/[./]+/g,"_").replace(/_html$/,""));return(a,l)=>{const c=cn("Content");return Y(),fe("div",{class:yt(["VPDoc",{"has-sidebar":j(n),"has-aside":j(i)}])},[ue(a.$slots,"doc-top",{},void 0,!0),me("div",Y1,[j(i)?(Y(),fe("div",{key:0,class:yt(["aside",{"left-aside":j(r)}])},[Z1,me("div",J1,[me("div",K1,[Fe(w1,null,{"aside-top":ye(()=>[ue(a.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":ye(()=>[ue(a.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":ye(()=>[ue(a.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":ye(()=>[ue(a.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":ye(()=>[ue(a.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":ye(()=>[ue(a.$slots,"aside-ads-after",{},void 0,!0)]),_:3})])])],2)):De("",!0),me("div",j1,[me("div",Q1,[ue(a.$slots,"doc-before",{},void 0,!0),me("main",eA,[Fe(c,{class:yt(["vp-doc",[o.value,j(e).externalLinkIcon&&"external-link-icon-enabled"]])},null,8,["class"])]),Fe(X1,null,{"doc-footer-before":ye(()=>[ue(a.$slots,"doc-footer-before",{},void 0,!0)]),_:3}),ue(a.$slots,"doc-after",{},void 0,!0)])])]),ue(a.$slots,"doc-bottom",{},void 0,!0)],2)}}}),nA=Ye(tA,[["__scopeId","data-v-39a288b8"]]),iA=Be({__name:"VPButton",props:{tag:{},size:{default:"medium"},theme:{default:"brand"},text:{},href:{},target:{},rel:{}},setup(s){const e=s,t=ke(()=>e.href&&Yd.test(e.href)),n=ke(()=>e.tag||e.href?"a":"button");return(i,r)=>(Y(),$e(Bs(n.value),{class:yt(["VPButton",[i.size,i.theme]]),href:i.href?j(Hu)(i.href):void 0,target:e.target??(t.value?"_blank":void 0),rel:e.rel??(t.value?"noreferrer":void 0)},{default:ye(()=>[Ht(ft(i.text),1)]),_:1},8,["class","href","target","rel"]))}}),sA=Ye(iA,[["__scopeId","data-v-cad61b99"]]),rA=["src","alt"],oA=Be({inheritAttrs:!1,__name:"VPImage",props:{image:{},alt:{}},setup(s){return(e,t)=>{const n=cn("VPImage",!0);return e.image?(Y(),fe(xt,{key:0},[typeof e.image=="string"||"src"in e.image?(Y(),fe("img",ia({key:0,class:"VPImage"},typeof e.image=="string"?e.$attrs:{...e.image,...e.$attrs},{src:j(Jc)(typeof e.image=="string"?e.image:e.image.src),alt:e.alt??(typeof e.image=="string"?"":e.image.alt||"")}),null,16,rA)):(Y(),fe(xt,{key:1},[Fe(n,ia({class:"dark",image:e.image.dark,alt:e.image.alt},e.$attrs),null,16,["image","alt"]),Fe(n,ia({class:"light",image:e.image.light,alt:e.image.alt},e.$attrs),null,16,["image","alt"])],64))],64)):De("",!0)}}}),wa=Ye(oA,[["__scopeId","data-v-8426fc1a"]]),aA=s=>(Wt("data-v-303bb580"),s=s(),$t(),s),lA={class:"container"},cA={class:"main"},uA={key:0,class:"name"},hA=["innerHTML"],dA=["innerHTML"],fA=["innerHTML"],pA={key:0,class:"actions"},mA={key:0,class:"image"},gA={class:"image-container"},vA=aA(()=>me("div",{class:"image-bg"},null,-1)),_A=Be({__name:"VPHero",props:{name:{},text:{},tagline:{},image:{},actions:{}},setup(s){const e=zr("hero-image-slot-exists");return(t,n)=>(Y(),fe("div",{class:yt(["VPHero",{"has-image":t.image||j(e)}])},[me("div",lA,[me("div",cA,[ue(t.$slots,"home-hero-info-before",{},void 0,!0),ue(t.$slots,"home-hero-info",{},()=>[t.name?(Y(),fe("h1",uA,[me("span",{innerHTML:t.name,class:"clip"},null,8,hA)])):De("",!0),t.text?(Y(),fe("p",{key:1,innerHTML:t.text,class:"text"},null,8,dA)):De("",!0),t.tagline?(Y(),fe("p",{key:2,innerHTML:t.tagline,class:"tagline"},null,8,fA)):De("",!0)],!0),ue(t.$slots,"home-hero-info-after",{},void 0,!0),t.actions?(Y(),fe("div",pA,[(Y(!0),fe(xt,null,Jt(t.actions,i=>(Y(),fe("div",{key:i.link,class:"action"},[Fe(sA,{tag:"a",size:"medium",theme:i.theme,text:i.text,href:i.link,target:i.target,rel:i.rel},null,8,["theme","text","href","target","rel"])]))),128))])):De("",!0),ue(t.$slots,"home-hero-actions-after",{},void 0,!0)]),t.image||j(e)?(Y(),fe("div",mA,[me("div",gA,[vA,ue(t.$slots,"home-hero-image",{},()=>[t.image?(Y(),$e(wa,{key:0,class:"image-src",image:t.image},null,8,["image"])):De("",!0)],!0)])])):De("",!0)])],2))}}),yA=Ye(_A,[["__scopeId","data-v-303bb580"]]),xA=Be({__name:"VPHomeHero",setup(s){const{frontmatter:e}=ot();return(t,n)=>j(e).hero?(Y(),$e(yA,{key:0,class:"VPHomeHero",name:j(e).hero.name,text:j(e).hero.text,tagline:j(e).hero.tagline,image:j(e).hero.image,actions:j(e).hero.actions},{"home-hero-info-before":ye(()=>[ue(t.$slots,"home-hero-info-before")]),"home-hero-info":ye(()=>[ue(t.$slots,"home-hero-info")]),"home-hero-info-after":ye(()=>[ue(t.$slots,"home-hero-info-after")]),"home-hero-actions-after":ye(()=>[ue(t.$slots,"home-hero-actions-after")]),"home-hero-image":ye(()=>[ue(t.$slots,"home-hero-image")]),_:3},8,["name","text","tagline","image","actions"])):De("",!0)}}),MA=s=>(Wt("data-v-a3976bdc"),s=s(),$t(),s),bA={class:"box"},SA={key:0,class:"icon"},wA=["innerHTML"],AA=["innerHTML"],TA=["innerHTML"],EA={key:4,class:"link-text"},CA={class:"link-text-value"},PA=MA(()=>me("span",{class:"vpi-arrow-right link-text-icon"},null,-1)),RA=Be({__name:"VPFeature",props:{icon:{},title:{},details:{},link:{},linkText:{},rel:{},target:{}},setup(s){return(e,t)=>(Y(),$e(Gn,{class:"VPFeature",href:e.link,rel:e.rel,target:e.target,"no-icon":!0,tag:e.link?"a":"div"},{default:ye(()=>[me("article",bA,[typeof e.icon=="object"&&e.icon.wrap?(Y(),fe("div",SA,[Fe(wa,{image:e.icon,alt:e.icon.alt,height:e.icon.height||48,width:e.icon.width||48},null,8,["image","alt","height","width"])])):typeof e.icon=="object"?(Y(),$e(wa,{key:1,image:e.icon,alt:e.icon.alt,height:e.icon.height||48,width:e.icon.width||48},null,8,["image","alt","height","width"])):e.icon?(Y(),fe("div",{key:2,class:"icon",innerHTML:e.icon},null,8,wA)):De("",!0),me("h2",{class:"title",innerHTML:e.title},null,8,AA),e.details?(Y(),fe("p",{key:3,class:"details",innerHTML:e.details},null,8,TA)):De("",!0),e.linkText?(Y(),fe("div",EA,[me("p",CA,[Ht(ft(e.linkText)+" ",1),PA])])):De("",!0)])]),_:1},8,["href","rel","target","tag"]))}}),IA=Ye(RA,[["__scopeId","data-v-a3976bdc"]]),LA={key:0,class:"VPFeatures"},NA={class:"container"},DA={class:"items"},UA=Be({__name:"VPFeatures",props:{features:{}},setup(s){const e=s,t=ke(()=>{const n=e.features.length;if(n){if(n===2)return"grid-2";if(n===3)return"grid-3";if(n%3===0)return"grid-6";if(n>3)return"grid-4"}else return});return(n,i)=>n.features?(Y(),fe("div",LA,[me("div",NA,[me("div",DA,[(Y(!0),fe(xt,null,Jt(n.features,r=>(Y(),fe("div",{key:r.title,class:yt(["item",[t.value]])},[Fe(IA,{icon:r.icon,title:r.title,details:r.details,link:r.link,"link-text":r.linkText,rel:r.rel,target:r.target},null,8,["icon","title","details","link","link-text","rel","target"])],2))),128))])])])):De("",!0)}}),OA=Ye(UA,[["__scopeId","data-v-a6181336"]]),FA=Be({__name:"VPHomeFeatures",setup(s){const{frontmatter:e}=ot();return(t,n)=>j(e).features?(Y(),$e(OA,{key:0,class:"VPHomeFeatures",features:j(e).features},null,8,["features"])):De("",!0)}}),kA=Be({__name:"VPHomeContent",setup(s){const{width:e}=Qm({initialWidth:0,includeScrollbar:!1});return(t,n)=>(Y(),fe("div",{class:"vp-doc container",style:Yc(j(e)?{"--vp-offset":`calc(50% - ${j(e)/2}px)`}:{})},[ue(t.$slots,"default",{},void 0,!0)],4))}}),BA=Ye(kA,[["__scopeId","data-v-8e2d4988"]]),zA={class:"VPHome"},VA=Be({__name:"VPHome",setup(s){const{frontmatter:e}=ot();return(t,n)=>{const i=cn("Content");return Y(),fe("div",zA,[ue(t.$slots,"home-hero-before",{},void 0,!0),Fe(xA,null,{"home-hero-info-before":ye(()=>[ue(t.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":ye(()=>[ue(t.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":ye(()=>[ue(t.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":ye(()=>[ue(t.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":ye(()=>[ue(t.$slots,"home-hero-image",{},void 0,!0)]),_:3}),ue(t.$slots,"home-hero-after",{},void 0,!0),ue(t.$slots,"home-features-before",{},void 0,!0),Fe(FA),ue(t.$slots,"home-features-after",{},void 0,!0),j(e).markdownStyles!==!1?(Y(),$e(BA,{key:0},{default:ye(()=>[Fe(i)]),_:1})):(Y(),$e(i,{key:1}))])}}}),HA=Ye(VA,[["__scopeId","data-v-686f80a6"]]),GA={},WA={class:"VPPage"};function $A(s,e){const t=cn("Content");return Y(),fe("div",WA,[ue(s.$slots,"page-top"),Fe(t),ue(s.$slots,"page-bottom")])}const XA=Ye(GA,[["render",$A]]),qA=Be({__name:"VPContent",setup(s){const{page:e,frontmatter:t}=ot(),{hasSidebar:n}=fi();return(i,r)=>(Y(),fe("div",{class:yt(["VPContent",{"has-sidebar":j(n),"is-home":j(t).layout==="home"}]),id:"VPContent"},[j(e).isNotFound?ue(i.$slots,"not-found",{key:0},()=>[Fe(n1)],!0):j(t).layout==="page"?(Y(),$e(XA,{key:1},{"page-top":ye(()=>[ue(i.$slots,"page-top",{},void 0,!0)]),"page-bottom":ye(()=>[ue(i.$slots,"page-bottom",{},void 0,!0)]),_:3})):j(t).layout==="home"?(Y(),$e(HA,{key:2},{"home-hero-before":ye(()=>[ue(i.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info-before":ye(()=>[ue(i.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":ye(()=>[ue(i.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":ye(()=>[ue(i.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":ye(()=>[ue(i.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":ye(()=>[ue(i.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":ye(()=>[ue(i.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":ye(()=>[ue(i.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":ye(()=>[ue(i.$slots,"home-features-after",{},void 0,!0)]),_:3})):j(t).layout&&j(t).layout!=="doc"?(Y(),$e(Bs(j(t).layout),{key:3})):(Y(),$e(nA,{key:4},{"doc-top":ye(()=>[ue(i.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":ye(()=>[ue(i.$slots,"doc-bottom",{},void 0,!0)]),"doc-footer-before":ye(()=>[ue(i.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":ye(()=>[ue(i.$slots,"doc-before",{},void 0,!0)]),"doc-after":ye(()=>[ue(i.$slots,"doc-after",{},void 0,!0)]),"aside-top":ye(()=>[ue(i.$slots,"aside-top",{},void 0,!0)]),"aside-outline-before":ye(()=>[ue(i.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":ye(()=>[ue(i.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":ye(()=>[ue(i.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":ye(()=>[ue(i.$slots,"aside-ads-after",{},void 0,!0)]),"aside-bottom":ye(()=>[ue(i.$slots,"aside-bottom",{},void 0,!0)]),_:3}))],2))}}),YA=Ye(qA,[["__scopeId","data-v-1428d186"]]),ZA={class:"container"},JA=["innerHTML"],KA=["innerHTML"],jA=Be({__name:"VPFooter",setup(s){const{theme:e,frontmatter:t}=ot(),{hasSidebar:n}=fi();return(i,r)=>j(e).footer&&j(t).footer!==!1?(Y(),fe("footer",{key:0,class:yt(["VPFooter",{"has-sidebar":j(n)}])},[me("div",ZA,[j(e).footer.message?(Y(),fe("p",{key:0,class:"message",innerHTML:j(e).footer.message},null,8,JA)):De("",!0),j(e).footer.copyright?(Y(),fe("p",{key:1,class:"copyright",innerHTML:j(e).footer.copyright},null,8,KA)):De("",!0)])],2)):De("",!0)}}),QA=Ye(jA,[["__scopeId","data-v-e315a0ad"]]);function eT(){const{theme:s,frontmatter:e}=ot(),t=Rn([]),n=ke(()=>t.value.length>0);return Aa(()=>{t.value=Gu(e.value.outline??s.value.outline)}),{headers:t,hasLocalNav:n}}const tT=s=>(Wt("data-v-17a5e62e"),s=s(),$t(),s),nT={class:"menu-text"},iT=tT(()=>me("span",{class:"vpi-chevron-right icon"},null,-1)),sT={class:"header"},rT={class:"outline"},oT=Be({__name:"VPLocalNavOutlineDropdown",props:{headers:{},navHeight:{}},setup(s){const e=s,{theme:t}=ot(),n=Ge(!1),i=Ge(0),r=Ge(),o=Ge();function a(h){var d;(d=r.value)!=null&&d.contains(h.target)||(n.value=!1)}Ct(n,h=>{if(h){document.addEventListener("click",a);return}document.removeEventListener("click",a)}),jl("Escape",()=>{n.value=!1}),Aa(()=>{n.value=!1});function l(){n.value=!n.value,i.value=window.innerHeight+Math.min(window.scrollY-e.navHeight,0)}function c(h){h.target.classList.contains("outline-link")&&(o.value&&(o.value.style.transition="none"),qc(()=>{n.value=!1}))}function u(){n.value=!1,window.scrollTo({top:0,left:0,behavior:"smooth"})}return(h,d)=>(Y(),fe("div",{class:"VPLocalNavOutlineDropdown",style:Yc({"--vp-vh":i.value+"px"}),ref_key:"main",ref:r},[h.headers.length>0?(Y(),fe("button",{key:0,onClick:l,class:yt({open:n.value})},[me("span",nT,ft(j(Tm)(j(t))),1),iT],2)):(Y(),fe("button",{key:1,onClick:u},ft(j(t).returnToTopLabel||"Return to top"),1)),Fe(Zc,{name:"flyout"},{default:ye(()=>[n.value?(Y(),fe("div",{key:0,ref_key:"items",ref:o,class:"items",onClick:c},[me("div",sT,[me("a",{class:"top-link",href:"#",onClick:u},ft(j(t).returnToTopLabel||"Return to top"),1)]),me("div",rT,[Fe(Em,{headers:h.headers},null,8,["headers"])])],512)):De("",!0)]),_:1})],4))}}),aT=Ye(oT,[["__scopeId","data-v-17a5e62e"]]),lT=s=>(Wt("data-v-a6f0e41e"),s=s(),$t(),s),cT={class:"container"},uT=["aria-expanded"],hT=lT(()=>me("span",{class:"vpi-align-left menu-icon"},null,-1)),dT={class:"menu-text"},fT=Be({__name:"VPLocalNav",props:{open:{type:Boolean}},emits:["open-menu"],setup(s){const{theme:e,frontmatter:t}=ot(),{hasSidebar:n}=fi(),{headers:i}=eT(),{y:r}=Zd(),o=Ge(0);Nn(()=>{o.value=parseInt(getComputedStyle(document.documentElement).getPropertyValue("--vp-nav-height"))}),Aa(()=>{i.value=Gu(t.value.outline??e.value.outline)});const a=ke(()=>i.value.length===0),l=ke(()=>a.value&&!n.value),c=ke(()=>({VPLocalNav:!0,"has-sidebar":n.value,empty:a.value,fixed:l.value}));return(u,h)=>j(t).layout!=="home"&&(!l.value||j(r)>=o.value)?(Y(),fe("div",{key:0,class:yt(c.value)},[me("div",cT,[j(n)?(Y(),fe("button",{key:0,class:"menu","aria-expanded":u.open,"aria-controls":"VPSidebarNav",onClick:h[0]||(h[0]=d=>u.$emit("open-menu"))},[hT,me("span",dT,ft(j(e).sidebarMenuLabel||"Menu"),1)],8,uT)):De("",!0),Fe(aT,{headers:j(i),navHeight:o.value},null,8,["headers","navHeight"])])],2)):De("",!0)}}),pT=Ye(fT,[["__scopeId","data-v-a6f0e41e"]]);function mT(){const s=Ge(!1);function e(){s.value=!0,window.addEventListener("resize",i)}function t(){s.value=!1,window.removeEventListener("resize",i)}function n(){s.value?t():e()}function i(){window.outerWidth>=768&&t()}const r=Vr();return Ct(()=>r.path,t),{isScreenOpen:s,openScreen:e,closeScreen:t,toggleScreen:n}}const gT={},vT={class:"VPSwitch",type:"button",role:"switch"},_T={class:"check"},yT={key:0,class:"icon"};function xT(s,e){return Y(),fe("button",vT,[me("span",_T,[s.$slots.default?(Y(),fe("span",yT,[ue(s.$slots,"default",{},void 0,!0)])):De("",!0)])])}const MT=Ye(gT,[["render",xT],["__scopeId","data-v-1d5665e3"]]),Pm=s=>(Wt("data-v-d1f28634"),s=s(),$t(),s),bT=Pm(()=>me("span",{class:"vpi-sun sun"},null,-1)),ST=Pm(()=>me("span",{class:"vpi-moon moon"},null,-1)),wT=Be({__name:"VPSwitchAppearance",setup(s){const{isDark:e,theme:t}=ot(),n=zr("toggle-appearance",()=>{e.value=!e.value}),i=ke(()=>e.value?t.value.lightModeSwitchTitle||"Switch to light theme":t.value.darkModeSwitchTitle||"Switch to dark theme");return(r,o)=>(Y(),$e(MT,{title:i.value,class:"VPSwitchAppearance","aria-checked":j(e),onClick:j(n)},{default:ye(()=>[bT,ST]),_:1},8,["title","aria-checked","onClick"]))}}),Wu=Ye(wT,[["__scopeId","data-v-d1f28634"]]),AT={key:0,class:"VPNavBarAppearance"},TT=Be({__name:"VPNavBarAppearance",setup(s){const{site:e}=ot();return(t,n)=>j(e).appearance&&j(e).appearance!=="force-dark"?(Y(),fe("div",AT,[Fe(Wu)])):De("",!0)}}),ET=Ye(TT,[["__scopeId","data-v-e6aabb21"]]),$u=Ge();let Rm=!1,Jl=0;function CT(s){const e=Ge(!1);if(Ta){!Rm&&PT(),Jl++;const t=Ct($u,n=>{var i,r,o;n===s.el.value||(i=s.el.value)!=null&&i.contains(n)?(e.value=!0,(r=s.onFocus)==null||r.call(s)):(e.value=!1,(o=s.onBlur)==null||o.call(s))});Wn(()=>{t(),Jl--,Jl||RT()})}return gr(e)}function PT(){document.addEventListener("focusin",Im),Rm=!0,$u.value=document.activeElement}function RT(){document.removeEventListener("focusin",Im)}function Im(){$u.value=document.activeElement}const IT={class:"VPMenuLink"},LT=Be({__name:"VPMenuLink",props:{item:{}},setup(s){const{page:e}=ot();return(t,n)=>(Y(),fe("div",IT,[Fe(Gn,{class:yt({active:j(is)(j(e).relativePath,t.item.activeMatch||t.item.link,!!t.item.activeMatch)}),href:t.item.link,target:t.item.target,rel:t.item.rel},{default:ye(()=>[Ht(ft(t.item.text),1)]),_:1},8,["class","href","target","rel"])]))}}),sl=Ye(LT,[["__scopeId","data-v-43f1e123"]]),NT={class:"VPMenuGroup"},DT={key:0,class:"title"},UT=Be({__name:"VPMenuGroup",props:{text:{},items:{}},setup(s){return(e,t)=>(Y(),fe("div",NT,[e.text?(Y(),fe("p",DT,ft(e.text),1)):De("",!0),(Y(!0),fe(xt,null,Jt(e.items,n=>(Y(),fe(xt,null,["link"in n?(Y(),$e(sl,{key:0,item:n},null,8,["item"])):De("",!0)],64))),256))]))}}),OT=Ye(UT,[["__scopeId","data-v-69e747b5"]]),FT={class:"VPMenu"},kT={key:0,class:"items"},BT=Be({__name:"VPMenu",props:{items:{}},setup(s){return(e,t)=>(Y(),fe("div",FT,[e.items?(Y(),fe("div",kT,[(Y(!0),fe(xt,null,Jt(e.items,n=>(Y(),fe(xt,{key:n.text},["link"in n?(Y(),$e(sl,{key:0,item:n},null,8,["item"])):(Y(),$e(OT,{key:1,text:n.text,items:n.items},null,8,["text","items"]))],64))),128))])):De("",!0),ue(e.$slots,"default",{},void 0,!0)]))}}),zT=Ye(BT,[["__scopeId","data-v-e7ea1737"]]),VT=s=>(Wt("data-v-b6c34ac9"),s=s(),$t(),s),HT=["aria-expanded","aria-label"],GT={key:0,class:"text"},WT=["innerHTML"],$T=VT(()=>me("span",{class:"vpi-chevron-down text-icon"},null,-1)),XT={key:1,class:"vpi-more-horizontal icon"},qT={class:"menu"},YT=Be({__name:"VPFlyout",props:{icon:{},button:{},label:{},items:{}},setup(s){const e=Ge(!1),t=Ge();CT({el:t,onBlur:n});function n(){e.value=!1}return(i,r)=>(Y(),fe("div",{class:"VPFlyout",ref_key:"el",ref:t,onMouseenter:r[1]||(r[1]=o=>e.value=!0),onMouseleave:r[2]||(r[2]=o=>e.value=!1)},[me("button",{type:"button",class:"button","aria-haspopup":"true","aria-expanded":e.value,"aria-label":i.label,onClick:r[0]||(r[0]=o=>e.value=!e.value)},[i.button||i.icon?(Y(),fe("span",GT,[i.icon?(Y(),fe("span",{key:0,class:yt([i.icon,"option-icon"])},null,2)):De("",!0),i.button?(Y(),fe("span",{key:1,innerHTML:i.button},null,8,WT)):De("",!0),$T])):(Y(),fe("span",XT))],8,HT),me("div",qT,[Fe(zT,{items:i.items},{default:ye(()=>[ue(i.$slots,"default",{},void 0,!0)]),_:3},8,["items"])])],544))}}),Xu=Ye(YT,[["__scopeId","data-v-b6c34ac9"]]),ZT=["href","aria-label","innerHTML"],JT=Be({__name:"VPSocialLink",props:{icon:{},link:{},ariaLabel:{}},setup(s){const e=s,t=ke(()=>typeof e.icon=="object"?e.icon.svg:``);return(n,i)=>(Y(),fe("a",{class:"VPSocialLink no-icon",href:n.link,"aria-label":n.ariaLabel??(typeof n.icon=="string"?n.icon:""),target:"_blank",rel:"noopener",innerHTML:t.value},null,8,ZT))}}),KT=Ye(JT,[["__scopeId","data-v-eee4e7cb"]]),jT={class:"VPSocialLinks"},QT=Be({__name:"VPSocialLinks",props:{links:{}},setup(s){return(e,t)=>(Y(),fe("div",jT,[(Y(!0),fe(xt,null,Jt(e.links,({link:n,icon:i,ariaLabel:r})=>(Y(),$e(KT,{key:n,icon:i,link:n,ariaLabel:r},null,8,["icon","link","ariaLabel"]))),128))]))}}),qu=Ye(QT,[["__scopeId","data-v-7bc22406"]]),eE={key:0,class:"group translations"},tE={class:"trans-title"},nE={key:1,class:"group"},iE={class:"item appearance"},sE={class:"label"},rE={class:"appearance-action"},oE={key:2,class:"group"},aE={class:"item social-links"},lE=Be({__name:"VPNavBarExtra",setup(s){const{site:e,theme:t}=ot(),{localeLinks:n,currentLang:i}=to({correspondingLink:!0}),r=ke(()=>n.value.length&&i.value.label||e.value.appearance||t.value.socialLinks);return(o,a)=>r.value?(Y(),$e(Xu,{key:0,class:"VPNavBarExtra",label:"extra navigation"},{default:ye(()=>[j(n).length&&j(i).label?(Y(),fe("div",eE,[me("p",tE,ft(j(i).label),1),(Y(!0),fe(xt,null,Jt(j(n),l=>(Y(),$e(sl,{key:l.link,item:l},null,8,["item"]))),128))])):De("",!0),j(e).appearance&&j(e).appearance!=="force-dark"?(Y(),fe("div",nE,[me("div",iE,[me("p",sE,ft(j(t).darkModeSwitchLabel||"Appearance"),1),me("div",rE,[Fe(Wu)])])])):De("",!0),j(t).socialLinks?(Y(),fe("div",oE,[me("div",aE,[Fe(qu,{class:"social-links-list",links:j(t).socialLinks},null,8,["links"])])])):De("",!0)]),_:1})):De("",!0)}}),cE=Ye(lE,[["__scopeId","data-v-d0bd9dde"]]),uE=s=>(Wt("data-v-e5dd9c1c"),s=s(),$t(),s),hE=["aria-expanded"],dE=uE(()=>me("span",{class:"container"},[me("span",{class:"top"}),me("span",{class:"middle"}),me("span",{class:"bottom"})],-1)),fE=[dE],pE=Be({__name:"VPNavBarHamburger",props:{active:{type:Boolean}},emits:["click"],setup(s){return(e,t)=>(Y(),fe("button",{type:"button",class:yt(["VPNavBarHamburger",{active:e.active}]),"aria-label":"mobile navigation","aria-expanded":e.active,"aria-controls":"VPNavScreen",onClick:t[0]||(t[0]=n=>e.$emit("click"))},fE,10,hE))}}),mE=Ye(pE,[["__scopeId","data-v-e5dd9c1c"]]),gE=["innerHTML"],vE=Be({__name:"VPNavBarMenuLink",props:{item:{}},setup(s){const{page:e}=ot();return(t,n)=>(Y(),$e(Gn,{class:yt({VPNavBarMenuLink:!0,active:j(is)(j(e).relativePath,t.item.activeMatch||t.item.link,!!t.item.activeMatch)}),href:t.item.link,noIcon:t.item.noIcon,target:t.item.target,rel:t.item.rel,tabindex:"0"},{default:ye(()=>[me("span",{innerHTML:t.item.text},null,8,gE)]),_:1},8,["class","href","noIcon","target","rel"]))}}),_E=Ye(vE,[["__scopeId","data-v-9c663999"]]),yE=Be({__name:"VPNavBarMenuGroup",props:{item:{}},setup(s){const e=s,{page:t}=ot(),n=r=>"link"in r?is(t.value.relativePath,r.link,!!e.item.activeMatch):r.items.some(n),i=ke(()=>n(e.item));return(r,o)=>(Y(),$e(Xu,{class:yt({VPNavBarMenuGroup:!0,active:j(is)(j(t).relativePath,r.item.activeMatch,!!r.item.activeMatch)||i.value}),button:r.item.text,items:r.item.items},null,8,["class","button","items"]))}}),xE=s=>(Wt("data-v-7f418b0f"),s=s(),$t(),s),ME={key:0,"aria-labelledby":"main-nav-aria-label",class:"VPNavBarMenu"},bE=xE(()=>me("span",{id:"main-nav-aria-label",class:"visually-hidden"},"Main Navigation",-1)),SE=Be({__name:"VPNavBarMenu",setup(s){const{theme:e}=ot();return(t,n)=>j(e).nav?(Y(),fe("nav",ME,[bE,(Y(!0),fe(xt,null,Jt(j(e).nav,i=>(Y(),fe(xt,{key:i.text},["link"in i?(Y(),$e(_E,{key:0,item:i},null,8,["item"])):(Y(),$e(yE,{key:1,item:i},null,8,["item"]))],64))),128))])):De("",!0)}}),wE=Ye(SE,[["__scopeId","data-v-7f418b0f"]]);function AE(s){const{localeIndex:e,theme:t}=ot();function n(i){var g,v,m;const r=i.split("."),o=(g=t.value.search)==null?void 0:g.options,a=o&&typeof o=="object",l=a&&((m=(v=o.locales)==null?void 0:v[e.value])==null?void 0:m.translations)||null,c=a&&o.translations||null;let u=l,h=c,d=s;const f=r.pop();for(const p of r){let y=null;const _=d==null?void 0:d[p];_&&(y=d=_);const x=h==null?void 0:h[p];x&&(y=h=x);const A=u==null?void 0:u[p];A&&(y=u=A),_||(d=y),x||(h=y),A||(u=y)}return(u==null?void 0:u[f])??(h==null?void 0:h[f])??(d==null?void 0:d[f])??""}return n}const TE=["aria-label"],EE={class:"DocSearch-Button-Container"},CE=me("span",{class:"vp-icon DocSearch-Search-Icon"},null,-1),PE={class:"DocSearch-Button-Placeholder"},RE=me("span",{class:"DocSearch-Button-Keys"},[me("kbd",{class:"DocSearch-Button-Key"}),me("kbd",{class:"DocSearch-Button-Key"},"K")],-1),Wd=Be({__name:"VPNavBarSearchButton",setup(s){const t=AE({button:{buttonText:"Search",buttonAriaLabel:"Search"}});return(n,i)=>(Y(),fe("button",{type:"button",class:"DocSearch DocSearch-Button","aria-label":j(t)("button.buttonAriaLabel")},[me("span",EE,[CE,me("span",PE,ft(j(t)("button.buttonText")),1)]),RE],8,TE))}}),IE={class:"VPNavBarSearch"},LE={id:"local-search"},NE={key:1,id:"docsearch"},DE=Be({__name:"VPNavBarSearch",setup(s){const e=eg(()=>tg(()=>import("./VPLocalSearchBox.CGFBigMq.js"),__vite__mapDeps([0,1]))),t=()=>null,{theme:n}=ot(),i=Ge(!1),r=Ge(!1);Nn(()=>{});function o(){i.value||(i.value=!0,setTimeout(a,16))}function a(){const h=new Event("keydown");h.key="k",h.metaKey=!0,window.dispatchEvent(h),setTimeout(()=>{document.querySelector(".DocSearch-Modal")||a()},16)}function l(h){const d=h.target,f=d.tagName;return d.isContentEditable||f==="INPUT"||f==="SELECT"||f==="TEXTAREA"}const c=Ge(!1);jl("k",h=>{(h.ctrlKey||h.metaKey)&&(h.preventDefault(),c.value=!0)}),jl("/",h=>{l(h)||(h.preventDefault(),c.value=!0)});const u="local";return(h,d)=>{var f;return Y(),fe("div",IE,[j(u)==="local"?(Y(),fe(xt,{key:0},[c.value?(Y(),$e(j(e),{key:0,onClose:d[0]||(d[0]=g=>c.value=!1)})):De("",!0),me("div",LE,[Fe(Wd,{onClick:d[1]||(d[1]=g=>c.value=!0)})])],64)):j(u)==="algolia"?(Y(),fe(xt,{key:1},[i.value?(Y(),$e(j(t),{key:0,algolia:((f=j(n).search)==null?void 0:f.options)??j(n).algolia,onVnodeBeforeMount:d[2]||(d[2]=g=>r.value=!0)},null,8,["algolia"])):De("",!0),r.value?De("",!0):(Y(),fe("div",NE,[Fe(Wd,{onClick:o})]))],64)):De("",!0)])}}}),UE=Be({__name:"VPNavBarSocialLinks",setup(s){const{theme:e}=ot();return(t,n)=>j(e).socialLinks?(Y(),$e(qu,{key:0,class:"VPNavBarSocialLinks",links:j(e).socialLinks},null,8,["links"])):De("",!0)}}),OE=Ye(UE,[["__scopeId","data-v-0394ad82"]]),FE=["href","rel","target"],kE={key:1},BE={key:2},zE=Be({__name:"VPNavBarTitle",setup(s){const{site:e,theme:t}=ot(),{hasSidebar:n}=fi(),{currentLang:i}=to(),r=ke(()=>{var l;return typeof t.value.logoLink=="string"?t.value.logoLink:(l=t.value.logoLink)==null?void 0:l.link}),o=ke(()=>{var l;return typeof t.value.logoLink=="string"||(l=t.value.logoLink)==null?void 0:l.rel}),a=ke(()=>{var l;return typeof t.value.logoLink=="string"||(l=t.value.logoLink)==null?void 0:l.target});return(l,c)=>(Y(),fe("div",{class:yt(["VPNavBarTitle",{"has-sidebar":j(n)}])},[me("a",{class:"title",href:r.value??j(Hu)(j(i).link),rel:o.value,target:a.value},[ue(l.$slots,"nav-bar-title-before",{},void 0,!0),j(t).logo?(Y(),$e(wa,{key:0,class:"logo",image:j(t).logo},null,8,["image"])):De("",!0),j(t).siteTitle?(Y(),fe("span",kE,ft(j(t).siteTitle),1)):j(t).siteTitle===void 0?(Y(),fe("span",BE,ft(j(e).title),1)):De("",!0),ue(l.$slots,"nav-bar-title-after",{},void 0,!0)],8,FE)],2))}}),VE=Ye(zE,[["__scopeId","data-v-ab179fa1"]]),HE={class:"items"},GE={class:"title"},WE=Be({__name:"VPNavBarTranslations",setup(s){const{theme:e}=ot(),{localeLinks:t,currentLang:n}=to({correspondingLink:!0});return(i,r)=>j(t).length&&j(n).label?(Y(),$e(Xu,{key:0,class:"VPNavBarTranslations",icon:"vpi-languages",label:j(e).langMenuLabel||"Change language"},{default:ye(()=>[me("div",HE,[me("p",GE,ft(j(n).label),1),(Y(!0),fe(xt,null,Jt(j(t),o=>(Y(),$e(sl,{key:o.link,item:o},null,8,["item"]))),128))])]),_:1},8,["label"])):De("",!0)}}),$E=Ye(WE,[["__scopeId","data-v-88af2de4"]]),XE=s=>(Wt("data-v-ccf7ddec"),s=s(),$t(),s),qE={class:"wrapper"},YE={class:"container"},ZE={class:"title"},JE={class:"content"},KE={class:"content-body"},jE=XE(()=>me("div",{class:"divider"},[me("div",{class:"divider-line"})],-1)),QE=Be({__name:"VPNavBar",props:{isScreenOpen:{type:Boolean}},emits:["toggle-screen"],setup(s){const{y:e}=Zd(),{hasSidebar:t}=fi(),{frontmatter:n}=ot(),i=Ge({});return qd(()=>{i.value={"has-sidebar":t.value,home:n.value.layout==="home",top:e.value===0}}),(r,o)=>(Y(),fe("div",{class:yt(["VPNavBar",i.value])},[me("div",qE,[me("div",YE,[me("div",ZE,[Fe(VE,null,{"nav-bar-title-before":ye(()=>[ue(r.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":ye(()=>[ue(r.$slots,"nav-bar-title-after",{},void 0,!0)]),_:3})]),me("div",JE,[me("div",KE,[ue(r.$slots,"nav-bar-content-before",{},void 0,!0),Fe(DE,{class:"search"}),Fe(wE,{class:"menu"}),Fe($E,{class:"translations"}),Fe(ET,{class:"appearance"}),Fe(OE,{class:"social-links"}),Fe(cE,{class:"extra"}),ue(r.$slots,"nav-bar-content-after",{},void 0,!0),Fe(mE,{class:"hamburger",active:r.isScreenOpen,onClick:o[0]||(o[0]=a=>r.$emit("toggle-screen"))},null,8,["active"])])])])]),jE],2))}}),eC=Ye(QE,[["__scopeId","data-v-ccf7ddec"]]),tC={key:0,class:"VPNavScreenAppearance"},nC={class:"text"},iC=Be({__name:"VPNavScreenAppearance",setup(s){const{site:e,theme:t}=ot();return(n,i)=>j(e).appearance&&j(e).appearance!=="force-dark"?(Y(),fe("div",tC,[me("p",nC,ft(j(t).darkModeSwitchLabel||"Appearance"),1),Fe(Wu)])):De("",!0)}}),sC=Ye(iC,[["__scopeId","data-v-2d7af913"]]),rC=Be({__name:"VPNavScreenMenuLink",props:{item:{}},setup(s){const e=zr("close-screen");return(t,n)=>(Y(),$e(Gn,{class:"VPNavScreenMenuLink",href:t.item.link,target:t.item.target,rel:t.item.rel,onClick:j(e),innerHTML:t.item.text},null,8,["href","target","rel","onClick","innerHTML"]))}}),oC=Ye(rC,[["__scopeId","data-v-7f31e1f6"]]),aC=Be({__name:"VPNavScreenMenuGroupLink",props:{item:{}},setup(s){const e=zr("close-screen");return(t,n)=>(Y(),$e(Gn,{class:"VPNavScreenMenuGroupLink",href:t.item.link,target:t.item.target,rel:t.item.rel,onClick:j(e)},{default:ye(()=>[Ht(ft(t.item.text),1)]),_:1},8,["href","target","rel","onClick"]))}}),Lm=Ye(aC,[["__scopeId","data-v-19976ae1"]]),lC={class:"VPNavScreenMenuGroupSection"},cC={key:0,class:"title"},uC=Be({__name:"VPNavScreenMenuGroupSection",props:{text:{},items:{}},setup(s){return(e,t)=>(Y(),fe("div",lC,[e.text?(Y(),fe("p",cC,ft(e.text),1)):De("",!0),(Y(!0),fe(xt,null,Jt(e.items,n=>(Y(),$e(Lm,{key:n.text,item:n},null,8,["item"]))),128))]))}}),hC=Ye(uC,[["__scopeId","data-v-8133b170"]]),dC=s=>(Wt("data-v-ff6087d4"),s=s(),$t(),s),fC=["aria-controls","aria-expanded"],pC=["innerHTML"],mC=dC(()=>me("span",{class:"vpi-plus button-icon"},null,-1)),gC=["id"],vC={key:1,class:"group"},_C=Be({__name:"VPNavScreenMenuGroup",props:{text:{},items:{}},setup(s){const e=s,t=Ge(!1),n=ke(()=>`NavScreenGroup-${e.text.replace(" ","-").toLowerCase()}`);function i(){t.value=!t.value}return(r,o)=>(Y(),fe("div",{class:yt(["VPNavScreenMenuGroup",{open:t.value}])},[me("button",{class:"button","aria-controls":n.value,"aria-expanded":t.value,onClick:i},[me("span",{class:"button-text",innerHTML:r.text},null,8,pC),mC],8,fC),me("div",{id:n.value,class:"items"},[(Y(!0),fe(xt,null,Jt(r.items,a=>(Y(),fe(xt,{key:a.text},["link"in a?(Y(),fe("div",{key:a.text,class:"item"},[Fe(Lm,{item:a},null,8,["item"])])):(Y(),fe("div",vC,[Fe(hC,{text:a.text,items:a.items},null,8,["text","items"])]))],64))),128))],8,gC)],2))}}),yC=Ye(_C,[["__scopeId","data-v-ff6087d4"]]),xC={key:0,class:"VPNavScreenMenu"},MC=Be({__name:"VPNavScreenMenu",setup(s){const{theme:e}=ot();return(t,n)=>j(e).nav?(Y(),fe("nav",xC,[(Y(!0),fe(xt,null,Jt(j(e).nav,i=>(Y(),fe(xt,{key:i.text},["link"in i?(Y(),$e(oC,{key:0,item:i},null,8,["item"])):(Y(),$e(yC,{key:1,text:i.text||"",items:i.items},null,8,["text","items"]))],64))),128))])):De("",!0)}}),bC=Be({__name:"VPNavScreenSocialLinks",setup(s){const{theme:e}=ot();return(t,n)=>j(e).socialLinks?(Y(),$e(qu,{key:0,class:"VPNavScreenSocialLinks",links:j(e).socialLinks},null,8,["links"])):De("",!0)}}),Nm=s=>(Wt("data-v-858fe1a4"),s=s(),$t(),s),SC=Nm(()=>me("span",{class:"vpi-languages icon lang"},null,-1)),wC=Nm(()=>me("span",{class:"vpi-chevron-down icon chevron"},null,-1)),AC={class:"list"},TC=Be({__name:"VPNavScreenTranslations",setup(s){const{localeLinks:e,currentLang:t}=to({correspondingLink:!0}),n=Ge(!1);function i(){n.value=!n.value}return(r,o)=>j(e).length&&j(t).label?(Y(),fe("div",{key:0,class:yt(["VPNavScreenTranslations",{open:n.value}])},[me("button",{class:"title",onClick:i},[SC,Ht(" "+ft(j(t).label)+" ",1),wC]),me("ul",AC,[(Y(!0),fe(xt,null,Jt(j(e),a=>(Y(),fe("li",{key:a.link,class:"item"},[Fe(Gn,{class:"link",href:a.link},{default:ye(()=>[Ht(ft(a.text),1)]),_:2},1032,["href"])]))),128))])],2)):De("",!0)}}),EC=Ye(TC,[["__scopeId","data-v-858fe1a4"]]),CC={class:"container"},PC=Be({__name:"VPNavScreen",props:{open:{type:Boolean}},setup(s){const e=Ge(null),t=Jd(Ta?document.body:null);return(n,i)=>(Y(),$e(Zc,{name:"fade",onEnter:i[0]||(i[0]=r=>t.value=!0),onAfterLeave:i[1]||(i[1]=r=>t.value=!1)},{default:ye(()=>[n.open?(Y(),fe("div",{key:0,class:"VPNavScreen",ref_key:"screen",ref:e,id:"VPNavScreen"},[me("div",CC,[ue(n.$slots,"nav-screen-content-before",{},void 0,!0),Fe(MC,{class:"menu"}),Fe(EC,{class:"translations"}),Fe(sC,{class:"appearance"}),Fe(bC,{class:"social-links"}),ue(n.$slots,"nav-screen-content-after",{},void 0,!0)])],512)):De("",!0)]),_:3}))}}),RC=Ye(PC,[["__scopeId","data-v-cc5739dd"]]),IC={key:0,class:"VPNav"},LC=Be({__name:"VPNav",setup(s){const{isScreenOpen:e,closeScreen:t,toggleScreen:n}=mT(),{frontmatter:i}=ot(),r=ke(()=>i.value.navbar!==!1);return vr("close-screen",t),Ri(()=>{Ta&&document.documentElement.classList.toggle("hide-nav",!r.value)}),(o,a)=>r.value?(Y(),fe("header",IC,[Fe(eC,{"is-screen-open":j(e),onToggleScreen:j(n)},{"nav-bar-title-before":ye(()=>[ue(o.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":ye(()=>[ue(o.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":ye(()=>[ue(o.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":ye(()=>[ue(o.$slots,"nav-bar-content-after",{},void 0,!0)]),_:3},8,["is-screen-open","onToggleScreen"]),Fe(RC,{open:j(e)},{"nav-screen-content-before":ye(()=>[ue(o.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":ye(()=>[ue(o.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3},8,["open"])])):De("",!0)}}),NC=Ye(LC,[["__scopeId","data-v-ae24b3ad"]]),Dm=s=>(Wt("data-v-b8d55f3b"),s=s(),$t(),s),DC=["role","tabindex"],UC=Dm(()=>me("div",{class:"indicator"},null,-1)),OC=["onKeydown"],FC=Dm(()=>me("span",{class:"vpi-chevron-right caret-icon"},null,-1)),kC=[FC],BC={key:1,class:"items"},zC=Be({__name:"VPSidebarItem",props:{item:{},depth:{}},setup(s){const e=s,{collapsed:t,collapsible:n,isLink:i,isActiveLink:r,hasActiveLink:o,hasChildren:a,toggle:l}=o1(ke(()=>e.item)),c=ke(()=>a.value?"section":"div"),u=ke(()=>i.value?"a":"div"),h=ke(()=>a.value?e.depth+2===7?"p":`h${e.depth+2}`:"p"),d=ke(()=>i.value?void 0:"button"),f=ke(()=>[[`level-${e.depth}`],{collapsible:n.value},{collapsed:t.value},{"is-link":i.value},{"is-active":r.value},{"has-active":o.value}]);function g(m){"key"in m&&m.key!=="Enter"||!e.item.link&&l()}function v(){e.item.link&&l()}return(m,p)=>{const y=cn("VPSidebarItem",!0);return Y(),$e(Bs(c.value),{class:yt(["VPSidebarItem",f.value])},{default:ye(()=>[m.item.text?(Y(),fe("div",ia({key:0,class:"item",role:d.value},ng(m.item.items?{click:g,keydown:g}:{},!0),{tabindex:m.item.items&&0}),[UC,m.item.link?(Y(),$e(Gn,{key:0,tag:u.value,class:"link",href:m.item.link,rel:m.item.rel,target:m.item.target},{default:ye(()=>[(Y(),$e(Bs(h.value),{class:"text",innerHTML:m.item.text},null,8,["innerHTML"]))]),_:1},8,["tag","href","rel","target"])):(Y(),$e(Bs(h.value),{key:1,class:"text",innerHTML:m.item.text},null,8,["innerHTML"])),m.item.collapsed!=null&&m.item.items&&m.item.items.length?(Y(),fe("div",{key:2,class:"caret",role:"button","aria-label":"toggle section",onClick:v,onKeydown:ig(v,["enter"]),tabindex:"0"},kC,40,OC)):De("",!0)],16,DC)):De("",!0),m.item.items&&m.item.items.length?(Y(),fe("div",BC,[m.depth<5?(Y(!0),fe(xt,{key:0},Jt(m.item.items,_=>(Y(),$e(y,{key:_.text,item:_,depth:m.depth+1},null,8,["item","depth"]))),128)):De("",!0)])):De("",!0)]),_:1},8,["class"])}}}),VC=Ye(zC,[["__scopeId","data-v-b8d55f3b"]]),Um=s=>(Wt("data-v-575e6a36"),s=s(),$t(),s),HC=Um(()=>me("div",{class:"curtain"},null,-1)),GC={class:"nav",id:"VPSidebarNav","aria-labelledby":"sidebar-aria-label",tabindex:"-1"},WC=Um(()=>me("span",{class:"visually-hidden",id:"sidebar-aria-label"}," Sidebar Navigation ",-1)),$C=Be({__name:"VPSidebar",props:{open:{type:Boolean}},setup(s){const e=s,{sidebarGroups:t,hasSidebar:n}=fi(),i=Ge(null),r=Jd(Ta?document.body:null);return Ct([e,i],()=>{var o;e.open?(r.value=!0,(o=i.value)==null||o.focus()):r.value=!1},{immediate:!0,flush:"post"}),(o,a)=>j(n)?(Y(),fe("aside",{key:0,class:yt(["VPSidebar",{open:o.open}]),ref_key:"navEl",ref:i,onClick:a[0]||(a[0]=sg(()=>{},["stop"]))},[HC,me("nav",GC,[WC,ue(o.$slots,"sidebar-nav-before",{},void 0,!0),(Y(!0),fe(xt,null,Jt(j(t),l=>(Y(),fe("div",{key:l.text,class:"group"},[Fe(VC,{item:l,depth:0},null,8,["item"])]))),128)),ue(o.$slots,"sidebar-nav-after",{},void 0,!0)])],2)):De("",!0)}}),XC=Ye($C,[["__scopeId","data-v-575e6a36"]]),qC=Be({__name:"VPSkipLink",setup(s){const e=Vr(),t=Ge();Ct(()=>e.path,()=>t.value.focus());function n({target:i}){const r=document.getElementById(decodeURIComponent(i.hash).slice(1));if(r){const o=()=>{r.removeAttribute("tabindex"),r.removeEventListener("blur",o)};r.setAttribute("tabindex","-1"),r.addEventListener("blur",o),r.focus(),window.scrollTo(0,0)}}return(i,r)=>(Y(),fe(xt,null,[me("span",{ref_key:"backToTop",ref:t,tabindex:"-1"},null,512),me("a",{href:"#VPContent",class:"VPSkipLink visually-hidden",onClick:n}," Skip to content ")],64))}}),YC=Ye(qC,[["__scopeId","data-v-0f60ec36"]]),ZC=Be({__name:"Layout",setup(s){const{isOpen:e,open:t,close:n}=fi(),i=Vr();Ct(()=>i.path,n),r1(e,n);const{frontmatter:r}=ot(),o=Xd(),a=ke(()=>!!o["home-hero-image"]);return vr("hero-image-slot-exists",a),(l,c)=>{const u=cn("Content");return j(r).layout!==!1?(Y(),fe("div",{key:0,class:yt(["Layout",j(r).pageClass])},[ue(l.$slots,"layout-top",{},void 0,!0),Fe(YC),Fe(Ww,{class:"backdrop",show:j(e),onClick:j(n)},null,8,["show","onClick"]),Fe(NC,null,{"nav-bar-title-before":ye(()=>[ue(l.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":ye(()=>[ue(l.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":ye(()=>[ue(l.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":ye(()=>[ue(l.$slots,"nav-bar-content-after",{},void 0,!0)]),"nav-screen-content-before":ye(()=>[ue(l.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":ye(()=>[ue(l.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3}),Fe(pT,{open:j(e),onOpenMenu:j(t)},null,8,["open","onOpenMenu"]),Fe(XC,{open:j(e)},{"sidebar-nav-before":ye(()=>[ue(l.$slots,"sidebar-nav-before",{},void 0,!0)]),"sidebar-nav-after":ye(()=>[ue(l.$slots,"sidebar-nav-after",{},void 0,!0)]),_:3},8,["open"]),Fe(YA,null,{"page-top":ye(()=>[ue(l.$slots,"page-top",{},void 0,!0)]),"page-bottom":ye(()=>[ue(l.$slots,"page-bottom",{},void 0,!0)]),"not-found":ye(()=>[ue(l.$slots,"not-found",{},void 0,!0)]),"home-hero-before":ye(()=>[ue(l.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info-before":ye(()=>[ue(l.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":ye(()=>[ue(l.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":ye(()=>[ue(l.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":ye(()=>[ue(l.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":ye(()=>[ue(l.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":ye(()=>[ue(l.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":ye(()=>[ue(l.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":ye(()=>[ue(l.$slots,"home-features-after",{},void 0,!0)]),"doc-footer-before":ye(()=>[ue(l.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":ye(()=>[ue(l.$slots,"doc-before",{},void 0,!0)]),"doc-after":ye(()=>[ue(l.$slots,"doc-after",{},void 0,!0)]),"doc-top":ye(()=>[ue(l.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":ye(()=>[ue(l.$slots,"doc-bottom",{},void 0,!0)]),"aside-top":ye(()=>[ue(l.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":ye(()=>[ue(l.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":ye(()=>[ue(l.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":ye(()=>[ue(l.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":ye(()=>[ue(l.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":ye(()=>[ue(l.$slots,"aside-ads-after",{},void 0,!0)]),_:3}),Fe(QA),ue(l.$slots,"layout-bottom",{},void 0,!0)],2)):(Y(),$e(u,{key:1}))}}}),JC=Ye(ZC,[["__scopeId","data-v-5d98c3a5"]]),Om={Layout:JC,enhanceApp:({app:s})=>{s.component("Badge",Vw)}},KC=Be({__name:"HighlightTargetedHeading",setup(s){function e(){if(!window||!window.location||!window.location.hash)return;const n=decodeURIComponent(window.location.hash);if(!n)return;let i;try{i=document.querySelector(n)}catch(r){console.error(r);return}i&&(i.classList.contains("VPNolebaseHighlightTargetedHeading")||i.classList.add("VPNolebaseHighlightTargetedHeading"),i.classList.remove("VPNolebaseHighlightTargetedHeadingAnimated"),setTimeout(()=>{i&&i.classList.add("VPNolebaseHighlightTargetedHeadingAnimated")},10))}const t=Vr();return Nn(e),Ct(t,async()=>{await qc(),e()}),rg("hashchange",e),(n,i)=>ue(n.$slots,"default")}}),no=s=>(Wt("data-v-4f9a2448"),s=s(),$t(),s),jC={class:"background"},QC={class:"vp-doc"},eP=no(()=>me("a",{class:"h-card",rel:"me",href:"/about"},[me("img",{src:ag,alt:""}),Ht("The Paper Pilot")],-1)),tP=no(()=>me("a",{rel:"license",href:"https://creativecommons.org/licenses/by-nc-sa/4.0/"},"CC BY-NC-SA 4.0",-1)),nP=no(()=>me("div",null,"Any and all opinions listed here are my own and not representative of my employers; future, past and present.",-1)),iP=no(()=>me("div",null,[me("a",{href:"https://resume.incremental.social/thepaperpilot/thepaperpilot"},"Resume"),Ht(" (not actively seeking new opportunities).")],-1)),sP=no(()=>me("div",null,[Ht("Site built from "),me("a",{href:"https://code.incremental.social/thepaperpilot/pages/commit/50fc43997fde6ba5648dcf9bb2ad34df5e125be5"},"this commit"),Ht(" on "),me("time",null,"Thursday, November 28, 2024 at 22:20:23"),Ht(". "),me("a",{href:"https://www.thepaperpilot.org/licenses.txt"},"Legal disclaimers"),Ht(".")],-1)),rP=Be({__name:"Layout",setup(s){return(e,t)=>{const n=cn("TresOrthographicCamera"),i=cn("TresAmbientLight"),r=cn("ClientOnly");return Y(),$e(j(Om).Layout,null,{"layout-top":ye(()=>[Fe(j(KC)),Fe(r,null,{default:ye(()=>[me("div",jC,[Fe(j(Ow),null,{default:ye(()=>[Fe(n,{position:[0,0,10]}),Fe(i,{intensity:1}),(Y(),$e(og,null,{default:ye(()=>[Fe(zw)]),_:1}))]),_:1})])]),_:1})]),"layout-bottom":ye(()=>[me("footer",QC,[me("div",null,[Ht("CC "+ft(new Date().getFullYear())+" ",1),eP,Ht(". "),tP,Ht(".")]),nP,iP,sP])]),_:1})}}}),oP=Ye(rP,[["__scopeId","data-v-4f9a2448"]]),lP={...Om,Layout:oP};export{Pc as A,Bn as K,es as N,xg as R,N as V,zw as _,lP as a,AE as c,kw as n,xw as r,Ow as t,ot as u}; diff --git a/assets/garden_a-plea-to-organize_index.md.CyK1zn1I.js b/assets/garden_a-plea-to-organize_index.md.DmEe_rYO.js similarity index 99% rename from assets/garden_a-plea-to-organize_index.md.CyK1zn1I.js rename to assets/garden_a-plea-to-organize_index.md.DmEe_rYO.js index 6a5b832ae..d10f51b5c 100644 --- a/assets/garden_a-plea-to-organize_index.md.CyK1zn1I.js +++ b/assets/garden_a-plea-to-organize_index.md.DmEe_rYO.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as i,Q as e,K as s,u as t,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"A Plea to Organize",-1),c=["innerHTML"],u=n('
Referenced by:Leftism

If you take one message from this letter, let it be this: Organize! Seek out a local mutual aid group via Mutual Aid Hub or join a progressive political organization like the DSA. Whether you're providing aid, receiving it, or working alongside fellow progressives, solidarity is our strongest tool.

The following is both a call to action and a guide for building a socialist movement that will not only resist but overcome the regressive forces steering our nation.

The Democrat Party has Betrayed You

The US is also a one party state but with typical American extravagance, they have two of them.
-Julius Nyerere

Trump's victory isn't simply a failure of the American electorate—it highlights the absence of a true progressive candidate. The Democrat Party, despite its claims, hasn't delivered on key progressive issues. From the civil rights movement to women's suffrage to gay rights, change has always come from grassroots struggle, not the political elites. The Democrat party's consistent move rightward has betrayed working-class interests, serving capitalist agendas instead.

While the Biden administration touts economic recovery, public sentiment doesn't match. Wage stagnation, unaffordable housing, and unaddressed inflation expose the gap between their rhetoric and the lived experiences of most Americans. Despite popular support and a government trifecta, his administration failed to raise the national minimum wage or fix it to inflation. They've failed to institute or expand price controls on food or rent. They passed the inflation reduction act of 2022, but it was not enough.

Harris' platform was not even socially progressive, as evidenced by their non-action on trans rights. Harris dodging a question a month before the election about protecting trans rights by saying "follow the law", despite the law currently being transphobic and actively getting worse in many states. She then took a transmedicalist stance on trans rights, saying she only supported gender-affirming care when a doctor deemed it "medically necessary".

Harris campaigned on unity, which to her meant courting Republican figures, most notably Dick Cheney and his daughter Liz Cheney. This underscores the Democrats' strategy: appeal to the right, even at the expense of progressive values. This is why "pushing the party left" is a pipe dream - the DNC would rather lose elections than adopt a truly progressive platform. The most clear example of such resistance to progressivism is when they ensured Bernie Sanders could not win the 2016 primaries.

We Need a Progressive Movement

We may have all come on different ships, but we're in the same boat now.
- Dr. Martin Luther King Jr.

America is at a crossroads. The re-election of Trump signals a dangerous shift toward reactionary politics, but we can't rely on the Democratic Party to provide an alternative.

Direct action, especially mutual aid efforts, will be crucial in the coming years. Many marginalized communities will be targeted by the state, and we must be ready to provide support outside of traditional systems that have repeatedly failed them. You can find local mutual aid groups through Mutual Aid Hub, and help your local community.

Trans rights are currently under attack both nationally and in most states. You can use the Trans Legislation Tracker to keep up to date, and from there you can contact your representatives or join local protests.

Joining local progressive organizations, such as the Democratic Socialists of America (DSA) or even fully socialist ones like the Party for Socialism and Liberation (PSL), will help build a strong foundation for a larger political movement. These organizations can serve as vehicles for collective action, allowing us to pool resources, share knowledge, and coordinate efforts on a larger scale.

If you have local unions or cooperatives you can join or support, that will also help your fellow workers and increase the visibility across America of democratic socialist structures working.

Eventually, our goal must be to replace the Democrat party with a legitimately progressive party. Various progressive policies and ideals are gaining popularity across the nation, regardless of political affiliation: impactful policies like protecting abortion rights, raising the minimum wage, universal healthcare, or protecting trans people are supported by most Americans. This election campaign has shown us appealing to the right does not bring in new voters, so we must appeal to the left, addressing the material conditions of the working class and uniting people around a shared vision of a better future.

Don't be Neutral

First they came for the socialists, and I did not speak out—
Because I was not a socialist...
- Martin Niemöller

In times of political upheaval, apathy is a luxury we cannot afford. Choosing "neutrality" is tacitly supporting the status quo, which continues to harm marginalized communities and entrenches inequality. But worse than apathy is insisting on civility - demanding "polite" protests while ignoring the injustice that fuels them. As Dr. MLK Jr. warned, prioritizing order over justice will only perpetuate inequality. Real change requires confronting power structures directly, often outside the confines of "acceptable" political channels.

America's political system, with its electoral college, first-past-the-post voting, and powerful lobbying, is inherently undemocratic. These mechanisms are designed to preserve the status quo, limiting real choice and stifling progressive voices. History shows us that meaningful change has rarely come from the ballot box alone but from grassroots activism and sustained pressure. If we want to transform this system, we must do more than vote—we must mobilize, protest, and demand a better future.

Never be deceived that the rich will allow you to vote away their wealth.
- Lucy Parsons

Read Progressive Media

When I gave food to the poor, they called me a saint. When I asked why the poor have no food, they called me a Communist.
- Dom Helder Camara

Mainstream media, owned by the capitalist class, will frame progressive issues as divisive or fringe. They will cover our failures but not our successes, and certainly not report on when we need your help. To break out from this bias, use news sources like Jacobin, Current Affairs, and The Intercept. Check out FAIR, a progressive news source that tackles corporate bias in media. Educate yourself on progressive causes via accessible resources such as Second Thought and Our Changing Climate. And if you have the time, reading political theory and understanding class struggle empowers us to cut through propaganda and equip ourselves for the fight ahead. In a world of influencers and culture war politics, improving our political literacy and seeing beyond the Republican vs Democrat dichotomy is imperative.

The smart way to keep people passive and obedient is to strictly limit the spectrum of acceptable opinion, but allow very lively debate within that spectrum - even encourage the
more critical and dissident views. That gives people the sense.
that there's free thinking going on, while all the time the
presuppositions of the system are being reinforced by the
limits put on the range of the debate.
- Noam Chomsky

Conclusion

It is our duty to fight for our freedom.
It is our duty to win.
We must love each other and support each other.
We have nothing to lose but our chains.
- Assata Shakur

This is a frightening moment in our nation's history, but we are not powerless. By organizing, educating, and building solidarity, we can lay the foundation for a progressive future. Join an organization, get involved in mutual aid, and prepare to support a new party that prioritizes people over profit.

The path ahead is not easy, but it is necessary. Together, we will challenge the establishment, demand justice, and build a society that works for everyone. The struggle is just beginning—let's make sure it ends in victory.

',31),w=JSON.parse('{"title":"A Plea to Organize","description":"","frontmatter":{"public":"true","slug":"a-plea-to-organize","title":"A Plea to Organize","prev":false,"next":false},"headers":[],"relativePath":"garden/a-plea-to-organize/index.md","filePath":"garden/a-plea-to-organize/index.md"}'),p={name:"garden/a-plea-to-organize/index.md"},y=Object.assign(p,{setup(d){const a=o();return(g,m)=>(l(),i("div",null,[h,e("p",null,[s("1135 words, ~6 minute read. "),e("span",{innerHTML:t(r)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),u]))}});export{w as __pageData,y as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as i,Q as e,K as s,u as t,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"A Plea to Organize",-1),c=["innerHTML"],u=n('
Referenced by:Leftism

If you take one message from this letter, let it be this: Organize! Seek out a local mutual aid group via Mutual Aid Hub or join a progressive political organization like the DSA. Whether you're providing aid, receiving it, or working alongside fellow progressives, solidarity is our strongest tool.

The following is both a call to action and a guide for building a socialist movement that will not only resist but overcome the regressive forces steering our nation.

The Democrat Party has Betrayed You

The US is also a one party state but with typical American extravagance, they have two of them.
-Julius Nyerere

Trump's victory isn't simply a failure of the American electorate—it highlights the absence of a true progressive candidate. The Democrat Party, despite its claims, hasn't delivered on key progressive issues. From the civil rights movement to women's suffrage to gay rights, change has always come from grassroots struggle, not the political elites. The Democrat party's consistent move rightward has betrayed working-class interests, serving capitalist agendas instead.

While the Biden administration touts economic recovery, public sentiment doesn't match. Wage stagnation, unaffordable housing, and unaddressed inflation expose the gap between their rhetoric and the lived experiences of most Americans. Despite popular support and a government trifecta, his administration failed to raise the national minimum wage or fix it to inflation. They've failed to institute or expand price controls on food or rent. They passed the inflation reduction act of 2022, but it was not enough.

Harris' platform was not even socially progressive, as evidenced by their non-action on trans rights. Harris dodging a question a month before the election about protecting trans rights by saying "follow the law", despite the law currently being transphobic and actively getting worse in many states. She then took a transmedicalist stance on trans rights, saying she only supported gender-affirming care when a doctor deemed it "medically necessary".

Harris campaigned on unity, which to her meant courting Republican figures, most notably Dick Cheney and his daughter Liz Cheney. This underscores the Democrats' strategy: appeal to the right, even at the expense of progressive values. This is why "pushing the party left" is a pipe dream - the DNC would rather lose elections than adopt a truly progressive platform. The most clear example of such resistance to progressivism is when they ensured Bernie Sanders could not win the 2016 primaries.

We Need a Progressive Movement

We may have all come on different ships, but we're in the same boat now.
- Dr. Martin Luther King Jr.

America is at a crossroads. The re-election of Trump signals a dangerous shift toward reactionary politics, but we can't rely on the Democratic Party to provide an alternative.

Direct action, especially mutual aid efforts, will be crucial in the coming years. Many marginalized communities will be targeted by the state, and we must be ready to provide support outside of traditional systems that have repeatedly failed them. You can find local mutual aid groups through Mutual Aid Hub, and help your local community.

Trans rights are currently under attack both nationally and in most states. You can use the Trans Legislation Tracker to keep up to date, and from there you can contact your representatives or join local protests.

Joining local progressive organizations, such as the Democratic Socialists of America (DSA) or even fully socialist ones like the Party for Socialism and Liberation (PSL), will help build a strong foundation for a larger political movement. These organizations can serve as vehicles for collective action, allowing us to pool resources, share knowledge, and coordinate efforts on a larger scale.

If you have local unions or cooperatives you can join or support, that will also help your fellow workers and increase the visibility across America of democratic socialist structures working.

Eventually, our goal must be to replace the Democrat party with a legitimately progressive party. Various progressive policies and ideals are gaining popularity across the nation, regardless of political affiliation: impactful policies like protecting abortion rights, raising the minimum wage, universal healthcare, or protecting trans people are supported by most Americans. This election campaign has shown us appealing to the right does not bring in new voters, so we must appeal to the left, addressing the material conditions of the working class and uniting people around a shared vision of a better future.

Don't be Neutral

First they came for the socialists, and I did not speak out—
Because I was not a socialist...
- Martin Niemöller

In times of political upheaval, apathy is a luxury we cannot afford. Choosing "neutrality" is tacitly supporting the status quo, which continues to harm marginalized communities and entrenches inequality. But worse than apathy is insisting on civility - demanding "polite" protests while ignoring the injustice that fuels them. As Dr. MLK Jr. warned, prioritizing order over justice will only perpetuate inequality. Real change requires confronting power structures directly, often outside the confines of "acceptable" political channels.

America's political system, with its electoral college, first-past-the-post voting, and powerful lobbying, is inherently undemocratic. These mechanisms are designed to preserve the status quo, limiting real choice and stifling progressive voices. History shows us that meaningful change has rarely come from the ballot box alone but from grassroots activism and sustained pressure. If we want to transform this system, we must do more than vote—we must mobilize, protest, and demand a better future.

Never be deceived that the rich will allow you to vote away their wealth.
- Lucy Parsons

Read Progressive Media

When I gave food to the poor, they called me a saint. When I asked why the poor have no food, they called me a Communist.
- Dom Helder Camara

Mainstream media, owned by the capitalist class, will frame progressive issues as divisive or fringe. They will cover our failures but not our successes, and certainly not report on when we need your help. To break out from this bias, use news sources like Jacobin, Current Affairs, and The Intercept. Check out FAIR, a progressive news source that tackles corporate bias in media. Educate yourself on progressive causes via accessible resources such as Second Thought and Our Changing Climate. And if you have the time, reading political theory and understanding class struggle empowers us to cut through propaganda and equip ourselves for the fight ahead. In a world of influencers and culture war politics, improving our political literacy and seeing beyond the Republican vs Democrat dichotomy is imperative.

The smart way to keep people passive and obedient is to strictly limit the spectrum of acceptable opinion, but allow very lively debate within that spectrum - even encourage the
more critical and dissident views. That gives people the sense.
that there's free thinking going on, while all the time the
presuppositions of the system are being reinforced by the
limits put on the range of the debate.
- Noam Chomsky

Conclusion

It is our duty to fight for our freedom.
It is our duty to win.
We must love each other and support each other.
We have nothing to lose but our chains.
- Assata Shakur

This is a frightening moment in our nation's history, but we are not powerless. By organizing, educating, and building solidarity, we can lay the foundation for a progressive future. Join an organization, get involved in mutual aid, and prepare to support a new party that prioritizes people over profit.

The path ahead is not easy, but it is necessary. Together, we will challenge the establishment, demand justice, and build a society that works for everyone. The struggle is just beginning—let's make sure it ends in victory.

',31),w=JSON.parse('{"title":"A Plea to Organize","description":"","frontmatter":{"public":"true","slug":"a-plea-to-organize","title":"A Plea to Organize","prev":false,"next":false},"headers":[],"relativePath":"garden/a-plea-to-organize/index.md","filePath":"garden/a-plea-to-organize/index.md"}'),p={name:"garden/a-plea-to-organize/index.md"},y=Object.assign(p,{setup(d){const a=o();return(g,m)=>(l(),i("div",null,[h,e("p",null,[s("1135 words, ~6 minute read. "),e("span",{innerHTML:t(r)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),u]))}});export{w as __pageData,y as default}; diff --git a/assets/garden_a-plea-to-organize_index.md.CyK1zn1I.lean.js b/assets/garden_a-plea-to-organize_index.md.DmEe_rYO.lean.js similarity index 92% rename from assets/garden_a-plea-to-organize_index.md.CyK1zn1I.lean.js rename to assets/garden_a-plea-to-organize_index.md.DmEe_rYO.lean.js index 8f5e6c880..183f555aa 100644 --- a/assets/garden_a-plea-to-organize_index.md.CyK1zn1I.lean.js +++ b/assets/garden_a-plea-to-organize_index.md.DmEe_rYO.lean.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as i,Q as e,K as s,u as t,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"A Plea to Organize",-1),c=["innerHTML"],u=n("",31),w=JSON.parse('{"title":"A Plea to Organize","description":"","frontmatter":{"public":"true","slug":"a-plea-to-organize","title":"A Plea to Organize","prev":false,"next":false},"headers":[],"relativePath":"garden/a-plea-to-organize/index.md","filePath":"garden/a-plea-to-organize/index.md"}'),p={name:"garden/a-plea-to-organize/index.md"},y=Object.assign(p,{setup(d){const a=o();return(g,m)=>(l(),i("div",null,[h,e("p",null,[s("1135 words, ~6 minute read. "),e("span",{innerHTML:t(r)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),u]))}});export{w as __pageData,y as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as i,Q as e,K as s,u as t,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"A Plea to Organize",-1),c=["innerHTML"],u=n("",31),w=JSON.parse('{"title":"A Plea to Organize","description":"","frontmatter":{"public":"true","slug":"a-plea-to-organize","title":"A Plea to Organize","prev":false,"next":false},"headers":[],"relativePath":"garden/a-plea-to-organize/index.md","filePath":"garden/a-plea-to-organize/index.md"}'),p={name:"garden/a-plea-to-organize/index.md"},y=Object.assign(p,{setup(d){const a=o();return(g,m)=>(l(),i("div",null,[h,e("p",null,[s("1135 words, ~6 minute read. "),e("span",{innerHTML:t(r)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),u]))}});export{w as __pageData,y as default}; diff --git a/assets/garden_advent-incremental_index.md.CMk1AiJQ.js b/assets/garden_advent-incremental_index.md.BqEpHWsk.js similarity index 96% rename from assets/garden_advent-incremental_index.md.CMk1AiJQ.js rename to assets/garden_advent-incremental_index.md.BqEpHWsk.js index d9903c714..091b3abcf 100644 --- a/assets/garden_advent-incremental_index.md.CMk1AiJQ.js +++ b/assets/garden_advent-incremental_index.md.BqEpHWsk.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as r,q as s,Q as e,K as o,u as t,ag as d,p as i}from"./chunks/framework.Sr2_9k8k.js";const p=e("h1",{class:"p-name"},"Advent Incremental",-1),c=["innerHTML"],m=d('
Tags:My ProjectsProfectus

Play it here!

An Open Source game made in Profectus over the course of 1 month by myself and other devs I know in the Incremental Games community!

I had the idea of an advent-style game that unlocked new pieces of content every real-life day a couple days before December started.

This was one of the most hectic months of my life!

I'm super happy with how it turned out. It ended up being way more ambitious than I anticipated but the end result is super large and awesome!

The TV Tropes page on this game mentions some of the cool things about this game

',8),v=JSON.parse('{"title":"Advent Incremental","description":"","frontmatter":{"public":"true","slug":"advent-incremental","tags":["My Projects","Profectus"],"title":"Advent Incremental","prev":false,"next":false},"headers":[],"relativePath":"garden/advent-incremental/index.md","filePath":"garden/advent-incremental/index.md"}'),l={name:"garden/advent-incremental/index.md"},y=Object.assign(l,{setup(h){const a=r();return(u,f)=>(i(),s("div",null,[p,e("p",null,[o("104 words, ~1 minute read. "),e("span",{innerHTML:t(n)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),m]))}});export{v as __pageData,y as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as r,q as s,Q as e,K as o,u as t,ag as d,p as i}from"./chunks/framework.Sr2_9k8k.js";const p=e("h1",{class:"p-name"},"Advent Incremental",-1),c=["innerHTML"],m=d('
Tags:My ProjectsProfectus

Play it here!

An Open Source game made in Profectus over the course of 1 month by myself and other devs I know in the Incremental Games community!

I had the idea of an advent-style game that unlocked new pieces of content every real-life day a couple days before December started.

This was one of the most hectic months of my life!

I'm super happy with how it turned out. It ended up being way more ambitious than I anticipated but the end result is super large and awesome!

The TV Tropes page on this game mentions some of the cool things about this game

',8),v=JSON.parse('{"title":"Advent Incremental","description":"","frontmatter":{"public":"true","slug":"advent-incremental","tags":["My Projects","Profectus"],"title":"Advent Incremental","prev":false,"next":false},"headers":[],"relativePath":"garden/advent-incremental/index.md","filePath":"garden/advent-incremental/index.md"}'),l={name:"garden/advent-incremental/index.md"},y=Object.assign(l,{setup(h){const a=r();return(u,f)=>(i(),s("div",null,[p,e("p",null,[o("104 words, ~1 minute read. "),e("span",{innerHTML:t(n)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),m]))}});export{v as __pageData,y as default}; diff --git a/assets/garden_advent-incremental_index.md.CMk1AiJQ.lean.js b/assets/garden_advent-incremental_index.md.BqEpHWsk.lean.js similarity index 92% rename from assets/garden_advent-incremental_index.md.CMk1AiJQ.lean.js rename to assets/garden_advent-incremental_index.md.BqEpHWsk.lean.js index c9c7782e5..85d9250f5 100644 --- a/assets/garden_advent-incremental_index.md.CMk1AiJQ.lean.js +++ b/assets/garden_advent-incremental_index.md.BqEpHWsk.lean.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as r,q as s,Q as e,K as o,u as t,ag as d,p as i}from"./chunks/framework.Sr2_9k8k.js";const p=e("h1",{class:"p-name"},"Advent Incremental",-1),c=["innerHTML"],m=d("",8),v=JSON.parse('{"title":"Advent Incremental","description":"","frontmatter":{"public":"true","slug":"advent-incremental","tags":["My Projects","Profectus"],"title":"Advent Incremental","prev":false,"next":false},"headers":[],"relativePath":"garden/advent-incremental/index.md","filePath":"garden/advent-incremental/index.md"}'),l={name:"garden/advent-incremental/index.md"},y=Object.assign(l,{setup(h){const a=r();return(u,f)=>(i(),s("div",null,[p,e("p",null,[o("104 words, ~1 minute read. "),e("span",{innerHTML:t(n)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),m]))}});export{v as __pageData,y as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as r,q as s,Q as e,K as o,u as t,ag as d,p as i}from"./chunks/framework.Sr2_9k8k.js";const p=e("h1",{class:"p-name"},"Advent Incremental",-1),c=["innerHTML"],m=d("",8),v=JSON.parse('{"title":"Advent Incremental","description":"","frontmatter":{"public":"true","slug":"advent-incremental","tags":["My Projects","Profectus"],"title":"Advent Incremental","prev":false,"next":false},"headers":[],"relativePath":"garden/advent-incremental/index.md","filePath":"garden/advent-incremental/index.md"}'),l={name:"garden/advent-incremental/index.md"},y=Object.assign(l,{setup(h){const a=r();return(u,f)=>(i(),s("div",null,[p,e("p",null,[o("104 words, ~1 minute read. "),e("span",{innerHTML:t(n)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),m]))}});export{v as __pageData,y as default}; diff --git a/assets/garden_anarchism_index.md.Bi4VyWbV.js b/assets/garden_anarchism_index.md.CER_o3nm.js similarity index 99% rename from assets/garden_anarchism_index.md.Bi4VyWbV.js rename to assets/garden_anarchism_index.md.CER_o3nm.js index 4d36e6960..6107f1ade 100644 --- a/assets/garden_anarchism_index.md.Bi4VyWbV.js +++ b/assets/garden_anarchism_index.md.CER_o3nm.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as r,Q as e,K as n,u as a,ag as s,p as c}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Anarchism",-1),l=["innerHTML"],d=s('
Referenced by:Decentralized ModerationDigital LocalityIndividualismLeftismLocal CommunitiesMy Political BeliefsRepresentative Democracy

Anarchism is a political philosophy centered around the idea that authoritative hierarchies are unjust, and aim for a society completely devoid of a state. They see a state as inherently self-preservationist and oppressive, thus that it has no place in society nor the transition to an egalitarian society.

Broadly speaking, flavors of anarchism can fall into 3 categories: collectivist anarchism, which is what this article will focus on; individualist anarchism, which are right-wing versions of anarchism based on Individualism; and modern anarchism, which are adaptations of collectivist communism to include additional hierarchies, such as anarcha-feminism which seeks to abolish the patriarchy in addition to class hierarchy. I'm personally biased against individualist anarchism but align with the values present in many collectivist and modern flavors of anarchism. I believe an ideal society is one with strong Local Communities that operate as a collective; spreading power as thinly as possible to avoid the possibility of any individuals becoming corrupt and abusing their power.

Decision Making in Anarchy

Flavors of anarchy will differ on whether decision making should exist at all. Egoism, an individualist flavor of anarchism, argues against not only any kind of collective decision making, but against society itself. Collectivist flavors of anarchism typically allow for group decision making in some form.

Group decision making under anarchism is typically modeled after a flavor of democracy. Majoritarian democracy, or Direct Democracy , is the idea that everyone gets a single vote and a measure passes if most people are in favor of it. A Consensus Democracy as described in Consensus is the idea that measures should only pass if nobody is opposed to it. This typically means in lieu of voting, individuals can "block" a measure by saying they disagree with it in part of in whole, and the polity must then decide to drop the measure or tweak it until it can pass without any blocks. Some forms of consensus democracy will also allow for measures to pass despite a small number of blocks, for the sake of making it feasible without constant gridlock when scaling up.

There are criticism of group decision making as anti-anarchistic in any form. In both of these versions of democracy, the polity is collectively agreeing to have some form of rule or agreement in place, and once agreed to, an individual typically cannot rescind their consent to that rule or agreement. In majoritarian democracy, up to half the polity may have never even given consent for that rule in the first place. Even in consensus democracy, discussions will often break down into compromise and eventual resignation in order to get measures passed, which is not a "true" version of consent. Typically supporters of these decision making processes will justify them as necessary of a society to function.

I'm personally a fan of consensus democracy. I agree with the justification that a society will naturally and necessarily contain social relationships that lead to things like compromises, and that "persuasiveness" is a permissible hierarchy out of necessity for society to exist.

Democracy in Statist Society

As a quick aside, some anarchists are critical of the term "democracy" here, as it may carry baggage of how democracy is implemented in a statist society, or disingenuously try to copy over the positive associations democracy has within western society. An anarchist would typically flat out reject any form of Representative Democracy due to representatives inherently imperfectly abstracting the will of their constituency. They would argue representative democracy strictly gets better the closer you get to everyone having a representative that perfectly matches their positions on all issues, which is of course then equivalent to a direct democracy.

Assigning Roles in Anarchy

A flavor of anarchism that allows for group decision making typically also allows for roles to be assigned. If the group agreed that a specific person is in charge of making sure livestock don't escape, or another person is in charge of drafting a design for a new building being proposed, then that's completely fine. However, no person fulfilling a role should be considered un-replacable, as that imbues that person with unjust coercive power. That means roles should have redundancies and an answer for "what if this person threatens to stop performing their role unless we capitulate to their demands?"

Motivation Under Anarchy

Anarchism relies on the idea that there are enough individuals motivated to systemically fix problems that they will do so without direct personal gain (beyond the problem being solved), and that others will not block those efforts, even if the policy won't help them in particular. I believe this would and does hold true. I believe our society being filled with greedy individuals is primarily caused by our society rewarding greed (see Social Constructs and Materialism). Anarchy Works starts by addressing this argument. Without the profit motive and returning to a culture of collaboration and mutual aid, greed would for the most part become a non-factor in policy making. Those who are already at the top of the hierarchy don't want to lose their position, and have thus been propagandizing that hierarchies are necessary/inevitable, and even just. This concept gets discussed in The Alt-Right Playbook: Always a Bigger Fish.

Accountability under Anarchy

Anarchy requires Police Abolition, as a carceral state is, obviously, a state. Emma Goldman's essays on anarchism include a chapter on Prisons: A Social Crime and Failure. Suffice to say, there is no state sanctioned violence in a state-less society. With that in mind, if someone breaks a rule or otherwise acts anti-socially, the anarchist society will have to rely on other methods of accountability.

Like prison abolitionists, anarchists would prefer systemic solutions to problems. If someone had to steal food from another at risk of starving, the solution is to ensure food (and other needs like shelter and healthcare) are accessible to all. Technology has made it trivial to provide for everyone; In America, there is more food waste than it would take to feed all the hungry, and enough vacant houses to shelter all the homeless. The scarcity is artificial, created by and maintained by those at the top of the hierarchy.

After meeting everyone's needs, crimes should essentially go away. When accidents happen, there's no need for consequences but the community may make changes to help prevent accidents from re-occurring. If the incident was caused by someone's needs not being met (e.g. food or healthcare), then they should be supported rather than punished. For the remaining edge cases, there is typically reliance on social consequences. People are less likely to associate with someone with anti-social tendencies, and that person may eventually just have to leave the community if no one remains who is willing to associate with them. This should be exceedingly rare, however.

Scaling up Anarchy

A core principle of anarchism is "free association", referring to how individuals should be able to freely enter and leave agreements between anarchist organizations. This is freedom to collaborate with whoever and however you like. These organizations are then typically considered rather ephemeral; temporary arrangements that can dissolve at any time as the needs and desires of those within the arrangement change. Scaling this up, it applies to communities/polities as well. A community can freely enter or leave agreements with other communities, and individuals can freely enter and leave those communities.

One thing to be wary of with free association, is that it can incidentally support segregation. It's therefore important for communities to encourage diversity as much as they can, and refuse to associate with bigoted communities, theoretically discouraging those bigoted views through social and material isolation.

Bookchin, a philosopher who was anarchist but abandoned the term while remaining anti-statist, described a society called Communalism which effectively operated as a confederacy of communes. The communes would operate via consensus, and the confederacy by majoritarian rule, dictating things like allowing communes to join or leave the confederacy. This was an attempt at an alternative to anarchism that would more easily scale up, but is considered fairly controversial amongst anarchists.

There is an organizational concept called sociocracy that has roots in several proto-anarchist thinkers. Sociocracy For All describes it as "one particular way to put anarchist values into practice" in Sociocracy and Anarchism. Their structure closely resembles what I've described and advocated for here, and they've provided guides enabling many organizations to uphold anarchist values.

Anarchy and Capitalism

The definition of individualist anarchism, one of the three categories defined in the introduction, is quite contested amongst anarchists. Some deny that its distinct from collectivist socialism and worth consideration, others claim it includes anarcho-capitalism, and yet others deny that capitalism is even compatible with anarchism at all. As the broad categories are just a Social Construct trying to make it easier to analyze different flavors of anarchism, I think its sufficient to say individualist anarchism is not really a useful term, as it typically needs clarification upon use of what individualist anarchism means to that author specifically.

I will take a strong position in favor of the argument that capitalism is inherently incompatible with anarchism, though. Capitalism inherently forms hierarchies by introducing currency as a coercive force that is then required for continued survival. Anarcho-capitalism, the theoretical blending of capitalism and anarchism, argues for a stateless society with a market economy, effectively instituting laissez-faire economics. Anarcho-capitalism argues this market would regulate itself naturally due to the exchange of goods being purely voluntary, however this ignores capitalist incentives that would trend the economy towards wealth accumulating in the hands of the few. This creates a coercive hierarchy, which is not voluntary due to people's need for food, water, and shelter. The only way to avoid this unjust hierarchy would be with a form of regulatory body that would be nothing short of a state. Therefore, anarcho-capitalism is not compatible with anarchism, because despite their shared antipathy towards states, they do not share the underlying antipathy towards hierarchy.

Anarcho-capitalists argue that their vision of anarchism is the only form that could possibly exist in reality, as any other form necessitates a state in order to handle things like the redistribution of private property. However, this argument itself implies the necessity of private property as a concept. Collectivist forms of anarchy such as anarcho-communism or mutualism demonstrate how economies can work without private property.

Anarchy in the Workplace

Typical American corporations are very hierarchical, with a few hands at the top having ultimate say over the company - what it does, how much it pays its employees, who it fires, etc. Worker's co-operatives are alternatives to corporations that are entirely worker owned and operated, with a flat hierarchy that meaningfully improve worker's rights and help shift society more socialist.

This dynamic means technological progress works in employees' favor, rather than owners' (since the employees are the owners). For example, lets say some technological innovation made employees twice as productive. Under a capitalist structure, the owners would have no reason to increase compensation based on the increased production, and in fact would be discouraged from doing so. They'd likely either use the increased productivity to sell more products, or half the workforce to cut down on significant expenditures. Under a socialist or anarchist structure, the needs and desires of the people are most important, so workers are likely to either see increased compensation due to their increased productivity, or reduced hours without a reduction in compensation. The co-operative could still decide to also just utilize the increased productivity without reducing hours nor increasing compensation, but the decision to do so would have been consensually made by the workers themselves, not their boss.

China enacted a policy in 2024 to make all of its corporations operate democratically, with a "Employee Assembly" made up of up to 100 workers, that can decide on things like firing supervisors or, in big companies, appointing 1/3 of the board of directors. That goes a long way in democratizing the remaining private businesses in China.

',32),v=JSON.parse('{"title":"Anarchism","description":"","frontmatter":{"alias":"Anarchist, Anarchistic","public":"true","slug":"anarchism","title":"Anarchism","prev":false,"next":false},"headers":[],"relativePath":"garden/anarchism/index.md","filePath":"garden/anarchism/index.md"}'),m={name:"garden/anarchism/index.md"},w=Object.assign(m,{setup(u){const t=o();return(p,y)=>(c(),r("div",null,[h,e("p",null,[n("1821 words, ~10 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,l)]),d]))}});export{v as __pageData,w as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as r,Q as e,K as n,u as a,ag as s,p as c}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Anarchism",-1),l=["innerHTML"],d=s('
Referenced by:Decentralized ModerationDigital LocalityIndividualismLeftismLocal CommunitiesMy Political BeliefsRepresentative Democracy

Anarchism is a political philosophy centered around the idea that authoritative hierarchies are unjust, and aim for a society completely devoid of a state. They see a state as inherently self-preservationist and oppressive, thus that it has no place in society nor the transition to an egalitarian society.

Broadly speaking, flavors of anarchism can fall into 3 categories: collectivist anarchism, which is what this article will focus on; individualist anarchism, which are right-wing versions of anarchism based on Individualism; and modern anarchism, which are adaptations of collectivist communism to include additional hierarchies, such as anarcha-feminism which seeks to abolish the patriarchy in addition to class hierarchy. I'm personally biased against individualist anarchism but align with the values present in many collectivist and modern flavors of anarchism. I believe an ideal society is one with strong Local Communities that operate as a collective; spreading power as thinly as possible to avoid the possibility of any individuals becoming corrupt and abusing their power.

Decision Making in Anarchy

Flavors of anarchy will differ on whether decision making should exist at all. Egoism, an individualist flavor of anarchism, argues against not only any kind of collective decision making, but against society itself. Collectivist flavors of anarchism typically allow for group decision making in some form.

Group decision making under anarchism is typically modeled after a flavor of democracy. Majoritarian democracy, or Direct Democracy , is the idea that everyone gets a single vote and a measure passes if most people are in favor of it. A Consensus Democracy as described in Consensus is the idea that measures should only pass if nobody is opposed to it. This typically means in lieu of voting, individuals can "block" a measure by saying they disagree with it in part of in whole, and the polity must then decide to drop the measure or tweak it until it can pass without any blocks. Some forms of consensus democracy will also allow for measures to pass despite a small number of blocks, for the sake of making it feasible without constant gridlock when scaling up.

There are criticism of group decision making as anti-anarchistic in any form. In both of these versions of democracy, the polity is collectively agreeing to have some form of rule or agreement in place, and once agreed to, an individual typically cannot rescind their consent to that rule or agreement. In majoritarian democracy, up to half the polity may have never even given consent for that rule in the first place. Even in consensus democracy, discussions will often break down into compromise and eventual resignation in order to get measures passed, which is not a "true" version of consent. Typically supporters of these decision making processes will justify them as necessary of a society to function.

I'm personally a fan of consensus democracy. I agree with the justification that a society will naturally and necessarily contain social relationships that lead to things like compromises, and that "persuasiveness" is a permissible hierarchy out of necessity for society to exist.

Democracy in Statist Society

As a quick aside, some anarchists are critical of the term "democracy" here, as it may carry baggage of how democracy is implemented in a statist society, or disingenuously try to copy over the positive associations democracy has within western society. An anarchist would typically flat out reject any form of Representative Democracy due to representatives inherently imperfectly abstracting the will of their constituency. They would argue representative democracy strictly gets better the closer you get to everyone having a representative that perfectly matches their positions on all issues, which is of course then equivalent to a direct democracy.

Assigning Roles in Anarchy

A flavor of anarchism that allows for group decision making typically also allows for roles to be assigned. If the group agreed that a specific person is in charge of making sure livestock don't escape, or another person is in charge of drafting a design for a new building being proposed, then that's completely fine. However, no person fulfilling a role should be considered un-replacable, as that imbues that person with unjust coercive power. That means roles should have redundancies and an answer for "what if this person threatens to stop performing their role unless we capitulate to their demands?"

Motivation Under Anarchy

Anarchism relies on the idea that there are enough individuals motivated to systemically fix problems that they will do so without direct personal gain (beyond the problem being solved), and that others will not block those efforts, even if the policy won't help them in particular. I believe this would and does hold true. I believe our society being filled with greedy individuals is primarily caused by our society rewarding greed (see Social Constructs and Materialism). Anarchy Works starts by addressing this argument. Without the profit motive and returning to a culture of collaboration and mutual aid, greed would for the most part become a non-factor in policy making. Those who are already at the top of the hierarchy don't want to lose their position, and have thus been propagandizing that hierarchies are necessary/inevitable, and even just. This concept gets discussed in The Alt-Right Playbook: Always a Bigger Fish.

Accountability under Anarchy

Anarchy requires Police Abolition, as a carceral state is, obviously, a state. Emma Goldman's essays on anarchism include a chapter on Prisons: A Social Crime and Failure. Suffice to say, there is no state sanctioned violence in a state-less society. With that in mind, if someone breaks a rule or otherwise acts anti-socially, the anarchist society will have to rely on other methods of accountability.

Like prison abolitionists, anarchists would prefer systemic solutions to problems. If someone had to steal food from another at risk of starving, the solution is to ensure food (and other needs like shelter and healthcare) are accessible to all. Technology has made it trivial to provide for everyone; In America, there is more food waste than it would take to feed all the hungry, and enough vacant houses to shelter all the homeless. The scarcity is artificial, created by and maintained by those at the top of the hierarchy.

After meeting everyone's needs, crimes should essentially go away. When accidents happen, there's no need for consequences but the community may make changes to help prevent accidents from re-occurring. If the incident was caused by someone's needs not being met (e.g. food or healthcare), then they should be supported rather than punished. For the remaining edge cases, there is typically reliance on social consequences. People are less likely to associate with someone with anti-social tendencies, and that person may eventually just have to leave the community if no one remains who is willing to associate with them. This should be exceedingly rare, however.

Scaling up Anarchy

A core principle of anarchism is "free association", referring to how individuals should be able to freely enter and leave agreements between anarchist organizations. This is freedom to collaborate with whoever and however you like. These organizations are then typically considered rather ephemeral; temporary arrangements that can dissolve at any time as the needs and desires of those within the arrangement change. Scaling this up, it applies to communities/polities as well. A community can freely enter or leave agreements with other communities, and individuals can freely enter and leave those communities.

One thing to be wary of with free association, is that it can incidentally support segregation. It's therefore important for communities to encourage diversity as much as they can, and refuse to associate with bigoted communities, theoretically discouraging those bigoted views through social and material isolation.

Bookchin, a philosopher who was anarchist but abandoned the term while remaining anti-statist, described a society called Communalism which effectively operated as a confederacy of communes. The communes would operate via consensus, and the confederacy by majoritarian rule, dictating things like allowing communes to join or leave the confederacy. This was an attempt at an alternative to anarchism that would more easily scale up, but is considered fairly controversial amongst anarchists.

There is an organizational concept called sociocracy that has roots in several proto-anarchist thinkers. Sociocracy For All describes it as "one particular way to put anarchist values into practice" in Sociocracy and Anarchism. Their structure closely resembles what I've described and advocated for here, and they've provided guides enabling many organizations to uphold anarchist values.

Anarchy and Capitalism

The definition of individualist anarchism, one of the three categories defined in the introduction, is quite contested amongst anarchists. Some deny that its distinct from collectivist socialism and worth consideration, others claim it includes anarcho-capitalism, and yet others deny that capitalism is even compatible with anarchism at all. As the broad categories are just a Social Construct trying to make it easier to analyze different flavors of anarchism, I think its sufficient to say individualist anarchism is not really a useful term, as it typically needs clarification upon use of what individualist anarchism means to that author specifically.

I will take a strong position in favor of the argument that capitalism is inherently incompatible with anarchism, though. Capitalism inherently forms hierarchies by introducing currency as a coercive force that is then required for continued survival. Anarcho-capitalism, the theoretical blending of capitalism and anarchism, argues for a stateless society with a market economy, effectively instituting laissez-faire economics. Anarcho-capitalism argues this market would regulate itself naturally due to the exchange of goods being purely voluntary, however this ignores capitalist incentives that would trend the economy towards wealth accumulating in the hands of the few. This creates a coercive hierarchy, which is not voluntary due to people's need for food, water, and shelter. The only way to avoid this unjust hierarchy would be with a form of regulatory body that would be nothing short of a state. Therefore, anarcho-capitalism is not compatible with anarchism, because despite their shared antipathy towards states, they do not share the underlying antipathy towards hierarchy.

Anarcho-capitalists argue that their vision of anarchism is the only form that could possibly exist in reality, as any other form necessitates a state in order to handle things like the redistribution of private property. However, this argument itself implies the necessity of private property as a concept. Collectivist forms of anarchy such as anarcho-communism or mutualism demonstrate how economies can work without private property.

Anarchy in the Workplace

Typical American corporations are very hierarchical, with a few hands at the top having ultimate say over the company - what it does, how much it pays its employees, who it fires, etc. Worker's co-operatives are alternatives to corporations that are entirely worker owned and operated, with a flat hierarchy that meaningfully improve worker's rights and help shift society more socialist.

This dynamic means technological progress works in employees' favor, rather than owners' (since the employees are the owners). For example, lets say some technological innovation made employees twice as productive. Under a capitalist structure, the owners would have no reason to increase compensation based on the increased production, and in fact would be discouraged from doing so. They'd likely either use the increased productivity to sell more products, or half the workforce to cut down on significant expenditures. Under a socialist or anarchist structure, the needs and desires of the people are most important, so workers are likely to either see increased compensation due to their increased productivity, or reduced hours without a reduction in compensation. The co-operative could still decide to also just utilize the increased productivity without reducing hours nor increasing compensation, but the decision to do so would have been consensually made by the workers themselves, not their boss.

China enacted a policy in 2024 to make all of its corporations operate democratically, with a "Employee Assembly" made up of up to 100 workers, that can decide on things like firing supervisors or, in big companies, appointing 1/3 of the board of directors. That goes a long way in democratizing the remaining private businesses in China.

',32),v=JSON.parse('{"title":"Anarchism","description":"","frontmatter":{"alias":"Anarchist, Anarchistic","public":"true","slug":"anarchism","title":"Anarchism","prev":false,"next":false},"headers":[],"relativePath":"garden/anarchism/index.md","filePath":"garden/anarchism/index.md"}'),m={name:"garden/anarchism/index.md"},w=Object.assign(m,{setup(u){const t=o();return(p,y)=>(c(),r("div",null,[h,e("p",null,[n("1821 words, ~10 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,l)]),d]))}});export{v as __pageData,w as default}; diff --git a/assets/garden_anarchism_index.md.Bi4VyWbV.lean.js b/assets/garden_anarchism_index.md.CER_o3nm.lean.js similarity index 91% rename from assets/garden_anarchism_index.md.Bi4VyWbV.lean.js rename to assets/garden_anarchism_index.md.CER_o3nm.lean.js index bcfda082a..267616750 100644 --- a/assets/garden_anarchism_index.md.Bi4VyWbV.lean.js +++ b/assets/garden_anarchism_index.md.CER_o3nm.lean.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as r,Q as e,K as n,u as a,ag as s,p as c}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Anarchism",-1),l=["innerHTML"],d=s("",32),v=JSON.parse('{"title":"Anarchism","description":"","frontmatter":{"alias":"Anarchist, Anarchistic","public":"true","slug":"anarchism","title":"Anarchism","prev":false,"next":false},"headers":[],"relativePath":"garden/anarchism/index.md","filePath":"garden/anarchism/index.md"}'),m={name:"garden/anarchism/index.md"},w=Object.assign(m,{setup(u){const t=o();return(p,y)=>(c(),r("div",null,[h,e("p",null,[n("1821 words, ~10 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,l)]),d]))}});export{v as __pageData,w as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as r,Q as e,K as n,u as a,ag as s,p as c}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Anarchism",-1),l=["innerHTML"],d=s("",32),v=JSON.parse('{"title":"Anarchism","description":"","frontmatter":{"alias":"Anarchist, Anarchistic","public":"true","slug":"anarchism","title":"Anarchism","prev":false,"next":false},"headers":[],"relativePath":"garden/anarchism/index.md","filePath":"garden/anarchism/index.md"}'),m={name:"garden/anarchism/index.md"},w=Object.assign(m,{setup(u){const t=o();return(p,y)=>(c(),r("div",null,[h,e("p",null,[n("1821 words, ~10 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,l)]),d]))}});export{v as __pageData,w as default}; diff --git a/assets/garden_art-is-never-complete_index.md.BPd82nXo.js b/assets/garden_art-is-never-complete_index.md.BtIYQjow.js similarity index 96% rename from assets/garden_art-is-never-complete_index.md.BPd82nXo.js rename to assets/garden_art-is-never-complete_index.md.BtIYQjow.js index 6442f2dbf..6284b328a 100644 --- a/assets/garden_art-is-never-complete_index.md.BPd82nXo.js +++ b/assets/garden_art-is-never-complete_index.md.BtIYQjow.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as r,Q as e,K as t,u as n,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Art is Never Complete",-1),d=["innerHTML"],c=e("hr",null,null,-1),h=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/guide-to-incrementals/what-is-content/index.md"},"Guide to Incrementals/What is Content?")],-1),u=e("blockquote",null,[e("p",null,"Art is never finished, only abandoned. - Leonardo Da Vinci")],-1),m=e("p",null,[t("This quote intrigues me and feels quite relatable. I've struggled with perfectionism (and in fact it's a large theme in Kronos), something Leonardo famously did as well. This quote feels like an exit ticket to getting out of perfectionist thinking - if art is "),e("em",null,"never"),t(` finished, then when its "done" (abandoned) is arbitrary. Perhaps that's why Leonardo left so many WIPs behind in his journal - if the point at which you abandon them is arbitrary, then why not abandon projects early?`)],-1),y=JSON.parse('{"title":"Art is Never Complete","description":"","frontmatter":{"public":"true","slug":"art-is-never-complete","title":"Art is Never Complete","prev":false,"next":false},"headers":[],"relativePath":"garden/art-is-never-complete/index.md","filePath":"garden/art-is-never-complete/index.md"}'),p={name:"garden/art-is-never-complete/index.md"},x=Object.assign(p,{setup(f){const a=s();return(_,g)=>(o(),r("div",null,[l,e("p",null,[t("92 words, ~1 minute read. "),e("span",{innerHTML:n(i)[`site/${n(a).page.value.relativePath}`]},null,8,d)]),c,h,u,m]))}});export{y as __pageData,x as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as r,Q as e,K as t,u as n,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Art is Never Complete",-1),d=["innerHTML"],c=e("hr",null,null,-1),h=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/guide-to-incrementals/what-is-content/index.md"},"Guide to Incrementals/What is Content?")],-1),u=e("blockquote",null,[e("p",null,"Art is never finished, only abandoned. - Leonardo Da Vinci")],-1),m=e("p",null,[t("This quote intrigues me and feels quite relatable. I've struggled with perfectionism (and in fact it's a large theme in Kronos), something Leonardo famously did as well. This quote feels like an exit ticket to getting out of perfectionist thinking - if art is "),e("em",null,"never"),t(` finished, then when its "done" (abandoned) is arbitrary. Perhaps that's why Leonardo left so many WIPs behind in his journal - if the point at which you abandon them is arbitrary, then why not abandon projects early?`)],-1),y=JSON.parse('{"title":"Art is Never Complete","description":"","frontmatter":{"public":"true","slug":"art-is-never-complete","title":"Art is Never Complete","prev":false,"next":false},"headers":[],"relativePath":"garden/art-is-never-complete/index.md","filePath":"garden/art-is-never-complete/index.md"}'),p={name:"garden/art-is-never-complete/index.md"},x=Object.assign(p,{setup(f){const a=s();return(_,g)=>(o(),r("div",null,[l,e("p",null,[t("92 words, ~1 minute read. "),e("span",{innerHTML:n(i)[`site/${n(a).page.value.relativePath}`]},null,8,d)]),c,h,u,m]))}});export{y as __pageData,x as default}; diff --git a/assets/garden_art-is-never-complete_index.md.BPd82nXo.lean.js b/assets/garden_art-is-never-complete_index.md.BtIYQjow.lean.js similarity index 96% rename from assets/garden_art-is-never-complete_index.md.BPd82nXo.lean.js rename to assets/garden_art-is-never-complete_index.md.BtIYQjow.lean.js index 6442f2dbf..6284b328a 100644 --- a/assets/garden_art-is-never-complete_index.md.BPd82nXo.lean.js +++ b/assets/garden_art-is-never-complete_index.md.BtIYQjow.lean.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as r,Q as e,K as t,u as n,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Art is Never Complete",-1),d=["innerHTML"],c=e("hr",null,null,-1),h=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/guide-to-incrementals/what-is-content/index.md"},"Guide to Incrementals/What is Content?")],-1),u=e("blockquote",null,[e("p",null,"Art is never finished, only abandoned. - Leonardo Da Vinci")],-1),m=e("p",null,[t("This quote intrigues me and feels quite relatable. I've struggled with perfectionism (and in fact it's a large theme in Kronos), something Leonardo famously did as well. This quote feels like an exit ticket to getting out of perfectionist thinking - if art is "),e("em",null,"never"),t(` finished, then when its "done" (abandoned) is arbitrary. Perhaps that's why Leonardo left so many WIPs behind in his journal - if the point at which you abandon them is arbitrary, then why not abandon projects early?`)],-1),y=JSON.parse('{"title":"Art is Never Complete","description":"","frontmatter":{"public":"true","slug":"art-is-never-complete","title":"Art is Never Complete","prev":false,"next":false},"headers":[],"relativePath":"garden/art-is-never-complete/index.md","filePath":"garden/art-is-never-complete/index.md"}'),p={name:"garden/art-is-never-complete/index.md"},x=Object.assign(p,{setup(f){const a=s();return(_,g)=>(o(),r("div",null,[l,e("p",null,[t("92 words, ~1 minute read. "),e("span",{innerHTML:n(i)[`site/${n(a).page.value.relativePath}`]},null,8,d)]),c,h,u,m]))}});export{y as __pageData,x as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as r,Q as e,K as t,u as n,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Art is Never Complete",-1),d=["innerHTML"],c=e("hr",null,null,-1),h=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/guide-to-incrementals/what-is-content/index.md"},"Guide to Incrementals/What is Content?")],-1),u=e("blockquote",null,[e("p",null,"Art is never finished, only abandoned. - Leonardo Da Vinci")],-1),m=e("p",null,[t("This quote intrigues me and feels quite relatable. I've struggled with perfectionism (and in fact it's a large theme in Kronos), something Leonardo famously did as well. This quote feels like an exit ticket to getting out of perfectionist thinking - if art is "),e("em",null,"never"),t(` finished, then when its "done" (abandoned) is arbitrary. Perhaps that's why Leonardo left so many WIPs behind in his journal - if the point at which you abandon them is arbitrary, then why not abandon projects early?`)],-1),y=JSON.parse('{"title":"Art is Never Complete","description":"","frontmatter":{"public":"true","slug":"art-is-never-complete","title":"Art is Never Complete","prev":false,"next":false},"headers":[],"relativePath":"garden/art-is-never-complete/index.md","filePath":"garden/art-is-never-complete/index.md"}'),p={name:"garden/art-is-never-complete/index.md"},x=Object.assign(p,{setup(f){const a=s();return(_,g)=>(o(),r("div",null,[l,e("p",null,[t("92 words, ~1 minute read. "),e("span",{innerHTML:n(i)[`site/${n(a).page.value.relativePath}`]},null,8,d)]),c,h,u,m]))}});export{y as __pageData,x as default}; diff --git a/assets/garden_artificial-intelligence_index.md.CBlCYWkr.js b/assets/garden_artificial-intelligence_index.md.VFi9pcqA.js similarity index 97% rename from assets/garden_artificial-intelligence_index.md.CBlCYWkr.js rename to assets/garden_artificial-intelligence_index.md.VFi9pcqA.js index 9c36501db..614e9df65 100644 --- a/assets/garden_artificial-intelligence_index.md.CBlCYWkr.js +++ b/assets/garden_artificial-intelligence_index.md.VFi9pcqA.js @@ -1 +1 @@ -import{d as l}from"./chunks/git.data.D-Ga3RhB.js";import{M as r,q as i,Q as e,K as n,u as a,ag as o,p as s}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Artificial Intelligence",-1),d=["innerHTML"],p=o('
Referenced by:Command Palettes

Catch all term that refers to many different things

Generative AI

  • Models trained on large amounts of existing human made content in order to produce more of that content
  • Copyright concerns over how training data is obtained
  • Common Examples

Human + AI cooperation

',7),b=JSON.parse('{"title":"Artificial Intelligence","description":"","frontmatter":{"public":"true","slug":"artificial-intelligence","title":"Artificial Intelligence","prev":false,"next":false},"headers":[],"relativePath":"garden/artificial-intelligence/index.md","filePath":"garden/artificial-intelligence/index.md"}'),u={name:"garden/artificial-intelligence/index.md"},k=Object.assign(u,{setup(h){const t=r();return(m,f)=>(s(),i("div",null,[c,e("p",null,[n("101 words, ~1 minute read. "),e("span",{innerHTML:a(l)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),p]))}});export{b as __pageData,k as default}; +import{d as l}from"./chunks/git.data.BcrWSzMU.js";import{M as r,q as i,Q as e,K as n,u as a,ag as o,p as s}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Artificial Intelligence",-1),d=["innerHTML"],p=o('
Referenced by:Command Palettes

Catch all term that refers to many different things

Generative AI

  • Models trained on large amounts of existing human made content in order to produce more of that content
  • Copyright concerns over how training data is obtained
  • Common Examples

Human + AI cooperation

',7),b=JSON.parse('{"title":"Artificial Intelligence","description":"","frontmatter":{"public":"true","slug":"artificial-intelligence","title":"Artificial Intelligence","prev":false,"next":false},"headers":[],"relativePath":"garden/artificial-intelligence/index.md","filePath":"garden/artificial-intelligence/index.md"}'),u={name:"garden/artificial-intelligence/index.md"},k=Object.assign(u,{setup(h){const t=r();return(m,f)=>(s(),i("div",null,[c,e("p",null,[n("101 words, ~1 minute read. "),e("span",{innerHTML:a(l)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),p]))}});export{b as __pageData,k as default}; diff --git a/assets/garden_artificial-intelligence_index.md.CBlCYWkr.lean.js b/assets/garden_artificial-intelligence_index.md.VFi9pcqA.lean.js similarity index 92% rename from assets/garden_artificial-intelligence_index.md.CBlCYWkr.lean.js rename to assets/garden_artificial-intelligence_index.md.VFi9pcqA.lean.js index 296da11d3..3f8e871c2 100644 --- a/assets/garden_artificial-intelligence_index.md.CBlCYWkr.lean.js +++ b/assets/garden_artificial-intelligence_index.md.VFi9pcqA.lean.js @@ -1 +1 @@ -import{d as l}from"./chunks/git.data.D-Ga3RhB.js";import{M as r,q as i,Q as e,K as n,u as a,ag as o,p as s}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Artificial Intelligence",-1),d=["innerHTML"],p=o("",7),b=JSON.parse('{"title":"Artificial Intelligence","description":"","frontmatter":{"public":"true","slug":"artificial-intelligence","title":"Artificial Intelligence","prev":false,"next":false},"headers":[],"relativePath":"garden/artificial-intelligence/index.md","filePath":"garden/artificial-intelligence/index.md"}'),u={name:"garden/artificial-intelligence/index.md"},k=Object.assign(u,{setup(h){const t=r();return(m,f)=>(s(),i("div",null,[c,e("p",null,[n("101 words, ~1 minute read. "),e("span",{innerHTML:a(l)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),p]))}});export{b as __pageData,k as default}; +import{d as l}from"./chunks/git.data.BcrWSzMU.js";import{M as r,q as i,Q as e,K as n,u as a,ag as o,p as s}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Artificial Intelligence",-1),d=["innerHTML"],p=o("",7),b=JSON.parse('{"title":"Artificial Intelligence","description":"","frontmatter":{"public":"true","slug":"artificial-intelligence","title":"Artificial Intelligence","prev":false,"next":false},"headers":[],"relativePath":"garden/artificial-intelligence/index.md","filePath":"garden/artificial-intelligence/index.md"}'),u={name:"garden/artificial-intelligence/index.md"},k=Object.assign(u,{setup(h){const t=r();return(m,f)=>(s(),i("div",null,[c,e("p",null,[n("101 words, ~1 minute read. "),e("span",{innerHTML:a(l)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),p]))}});export{b as __pageData,k as default}; diff --git a/assets/garden_atproto_index.md.D9_7sfO7.js b/assets/garden_atproto_index.md.ITAYOGJR.js similarity index 95% rename from assets/garden_atproto_index.md.D9_7sfO7.js rename to assets/garden_atproto_index.md.ITAYOGJR.js index e70e40204..c9388da45 100644 --- a/assets/garden_atproto_index.md.D9_7sfO7.js +++ b/assets/garden_atproto_index.md.ITAYOGJR.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as s,Q as e,K as n,u as a,ag as d,p as i}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"ATProto",-1),c=["innerHTML"],p=d('
Referenced by:Decentralized ModerationFediverse

The AT Protocol is a protocol for Federated Social Media created by Bluesky. In comparison to other Fediverse protocols, ATProto is designed for a small number of large instances.

',3),T=JSON.parse('{"title":"ATProto","description":"","frontmatter":{"alias":"The AT Protocol","public":"true","slug":"atproto","title":"ATProto","prev":false,"next":false},"headers":[],"relativePath":"garden/atproto/index.md","filePath":"garden/atproto/index.md"}'),_={name:"garden/atproto/index.md"},P=Object.assign(_,{setup(f){const r=o();return(m,h)=>(i(),s("div",null,[l,e("p",null,[n("14 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,c)]),p]))}});export{T as __pageData,P as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as s,Q as e,K as n,u as a,ag as d,p as i}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"ATProto",-1),c=["innerHTML"],p=d('
Referenced by:Decentralized ModerationFediverse

The AT Protocol is a protocol for Federated Social Media created by Bluesky. In comparison to other Fediverse protocols, ATProto is designed for a small number of large instances.

',3),T=JSON.parse('{"title":"ATProto","description":"","frontmatter":{"alias":"The AT Protocol","public":"true","slug":"atproto","title":"ATProto","prev":false,"next":false},"headers":[],"relativePath":"garden/atproto/index.md","filePath":"garden/atproto/index.md"}'),_={name:"garden/atproto/index.md"},P=Object.assign(_,{setup(f){const r=o();return(m,h)=>(i(),s("div",null,[l,e("p",null,[n("14 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,c)]),p]))}});export{T as __pageData,P as default}; diff --git a/assets/garden_atproto_index.md.D9_7sfO7.lean.js b/assets/garden_atproto_index.md.ITAYOGJR.lean.js similarity index 91% rename from assets/garden_atproto_index.md.D9_7sfO7.lean.js rename to assets/garden_atproto_index.md.ITAYOGJR.lean.js index c3f8586b7..27ce52819 100644 --- a/assets/garden_atproto_index.md.D9_7sfO7.lean.js +++ b/assets/garden_atproto_index.md.ITAYOGJR.lean.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as s,Q as e,K as n,u as a,ag as d,p as i}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"ATProto",-1),c=["innerHTML"],p=d("",3),T=JSON.parse('{"title":"ATProto","description":"","frontmatter":{"alias":"The AT Protocol","public":"true","slug":"atproto","title":"ATProto","prev":false,"next":false},"headers":[],"relativePath":"garden/atproto/index.md","filePath":"garden/atproto/index.md"}'),_={name:"garden/atproto/index.md"},P=Object.assign(_,{setup(f){const r=o();return(m,h)=>(i(),s("div",null,[l,e("p",null,[n("14 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,c)]),p]))}});export{T as __pageData,P as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as s,Q as e,K as n,u as a,ag as d,p as i}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"ATProto",-1),c=["innerHTML"],p=d("",3),T=JSON.parse('{"title":"ATProto","description":"","frontmatter":{"alias":"The AT Protocol","public":"true","slug":"atproto","title":"ATProto","prev":false,"next":false},"headers":[],"relativePath":"garden/atproto/index.md","filePath":"garden/atproto/index.md"}'),_={name:"garden/atproto/index.md"},P=Object.assign(_,{setup(f){const r=o();return(m,h)=>(i(),s("div",null,[l,e("p",null,[n("14 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,c)]),p]))}});export{T as __pageData,P as default}; diff --git a/assets/garden_babble-buds_index.md.DxmqVoTA.js b/assets/garden_babble-buds_index.md.CRllazQ1.js similarity index 96% rename from assets/garden_babble-buds_index.md.DxmqVoTA.js rename to assets/garden_babble-buds_index.md.CRllazQ1.js index 40bcc09fd..7a89bb876 100644 --- a/assets/garden_babble-buds_index.md.DxmqVoTA.js +++ b/assets/garden_babble-buds_index.md.CRllazQ1.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as o,Q as e,K as n,u as t,ag as i,p as b}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Babble Buds",-1),l=["innerHTML"],p=i('
Tags:My Projects

Babble Buds is a tool for creating puppets and interacting with puppets controlled by others on a shared stage

Note: I need to move the website off replit because of their monetization strategy changing. In the meantime, you can check it out from its github repository

Inspired by Puppet Pals by Robert Moran

Intended for use in RPG Campaigns

The renderer was separated into its own project, babble.js, so it could be used for stuff like cutscenes

I ported the engine to C# and used it for the cutscenes in Dice Armor

  • I don't believe I ever separated it out into its own project, but you can find the code here
',9),g=JSON.parse('{"title":"Babble Buds","description":"","frontmatter":{"public":"true","slug":"babble-buds","tags":["My Projects"],"title":"Babble Buds","prev":false,"next":false},"headers":[],"relativePath":"garden/babble-buds/index.md","filePath":"garden/babble-buds/index.md"}'),c={name:"garden/babble-buds/index.md"},y=Object.assign(c,{setup(u){const a=s();return(h,_)=>(b(),o("div",null,[d,e("p",null,[n("113 words, ~1 minute read. "),e("span",{innerHTML:t(r)[`site/${t(a).page.value.relativePath}`]},null,8,l)]),p]))}});export{g as __pageData,y as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as o,Q as e,K as n,u as t,ag as i,p as b}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Babble Buds",-1),l=["innerHTML"],p=i('
Tags:My Projects

Babble Buds is a tool for creating puppets and interacting with puppets controlled by others on a shared stage

Note: I need to move the website off replit because of their monetization strategy changing. In the meantime, you can check it out from its github repository

Inspired by Puppet Pals by Robert Moran

Intended for use in RPG Campaigns

The renderer was separated into its own project, babble.js, so it could be used for stuff like cutscenes

I ported the engine to C# and used it for the cutscenes in Dice Armor

  • I don't believe I ever separated it out into its own project, but you can find the code here
',9),g=JSON.parse('{"title":"Babble Buds","description":"","frontmatter":{"public":"true","slug":"babble-buds","tags":["My Projects"],"title":"Babble Buds","prev":false,"next":false},"headers":[],"relativePath":"garden/babble-buds/index.md","filePath":"garden/babble-buds/index.md"}'),c={name:"garden/babble-buds/index.md"},y=Object.assign(c,{setup(u){const a=s();return(h,_)=>(b(),o("div",null,[d,e("p",null,[n("113 words, ~1 minute read. "),e("span",{innerHTML:t(r)[`site/${t(a).page.value.relativePath}`]},null,8,l)]),p]))}});export{g as __pageData,y as default}; diff --git a/assets/garden_babble-buds_index.md.DxmqVoTA.lean.js b/assets/garden_babble-buds_index.md.CRllazQ1.lean.js similarity index 91% rename from assets/garden_babble-buds_index.md.DxmqVoTA.lean.js rename to assets/garden_babble-buds_index.md.CRllazQ1.lean.js index b5aa4dc8f..58d457063 100644 --- a/assets/garden_babble-buds_index.md.DxmqVoTA.lean.js +++ b/assets/garden_babble-buds_index.md.CRllazQ1.lean.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as o,Q as e,K as n,u as t,ag as i,p as b}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Babble Buds",-1),l=["innerHTML"],p=i("",9),g=JSON.parse('{"title":"Babble Buds","description":"","frontmatter":{"public":"true","slug":"babble-buds","tags":["My Projects"],"title":"Babble Buds","prev":false,"next":false},"headers":[],"relativePath":"garden/babble-buds/index.md","filePath":"garden/babble-buds/index.md"}'),c={name:"garden/babble-buds/index.md"},y=Object.assign(c,{setup(u){const a=s();return(h,_)=>(b(),o("div",null,[d,e("p",null,[n("113 words, ~1 minute read. "),e("span",{innerHTML:t(r)[`site/${t(a).page.value.relativePath}`]},null,8,l)]),p]))}});export{g as __pageData,y as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as o,Q as e,K as n,u as t,ag as i,p as b}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Babble Buds",-1),l=["innerHTML"],p=i("",9),g=JSON.parse('{"title":"Babble Buds","description":"","frontmatter":{"public":"true","slug":"babble-buds","tags":["My Projects"],"title":"Babble Buds","prev":false,"next":false},"headers":[],"relativePath":"garden/babble-buds/index.md","filePath":"garden/babble-buds/index.md"}'),c={name:"garden/babble-buds/index.md"},y=Object.assign(c,{setup(u){const a=s();return(h,_)=>(b(),o("div",null,[d,e("p",null,[n("113 words, ~1 minute read. "),e("span",{innerHTML:t(r)[`site/${t(a).page.value.relativePath}`]},null,8,l)]),p]))}});export{g as __pageData,y as default}; diff --git a/assets/garden_capture-the-citadel_index.md.-br6Pcc8.js b/assets/garden_capture-the-citadel_index.md.CiAmkxr4.js similarity index 95% rename from assets/garden_capture-the-citadel_index.md.-br6Pcc8.js rename to assets/garden_capture-the-citadel_index.md.CiAmkxr4.js index 7db2f5cc1..67b9bce78 100644 --- a/assets/garden_capture-the-citadel_index.md.-br6Pcc8.js +++ b/assets/garden_capture-the-citadel_index.md.CiAmkxr4.js @@ -1 +1 @@ -import{M as s,q as n,Q as e,K as t,u as a,ah as i,p as l}from"./chunks/framework.Sr2_9k8k.js";import{d as o}from"./chunks/git.data.D-Ga3RhB.js";const c=e("h1",{class:"p-name"},"Capture the Citadel",-1),d=["innerHTML"],p=e("hr",null,null,-1),h=e("details",null,[e("summary",null,"Tags:"),e("a",{href:"/garden/my-projects/index.md"},"My Projects")],-1),u=e("p",null,"A 3D VR re-envisioning of a Slay the Spire-style game by Anthony Lawn and Grant Barbee for their VR class in college's final project.",-1),_=e("p",null,[t("For more details, visit "),e("a",{href:"https://grantcbarbee.github.io/conquer-the-citadel.html",target:"_blank",rel:"noreferrer"},"Grant's page on the game"),t(".")],-1),m=e("div",{class:"img-container"},[e("img",{src:i,title:"screenshot.png"})],-1),C=JSON.parse('{"title":"Capture the Citadel","description":"","frontmatter":{"public":"true","slug":"capture-the-citadel","tags":["My Projects"],"title":"Capture the Citadel","prev":false,"next":false},"headers":[],"relativePath":"garden/capture-the-citadel/index.md","filePath":"garden/capture-the-citadel/index.md"}'),g={name:"garden/capture-the-citadel/index.md"},j=Object.assign(g,{setup(f){const r=s();return(b,v)=>(l(),n("div",null,[c,e("p",null,[t("39 words, ~0 minute read. "),e("span",{innerHTML:a(o)[`site/${a(r).page.value.relativePath}`]},null,8,d)]),p,h,u,_,m]))}});export{C as __pageData,j as default}; +import{M as s,q as n,Q as e,K as t,u as a,ah as i,p as l}from"./chunks/framework.Sr2_9k8k.js";import{d as o}from"./chunks/git.data.BcrWSzMU.js";const c=e("h1",{class:"p-name"},"Capture the Citadel",-1),d=["innerHTML"],p=e("hr",null,null,-1),h=e("details",null,[e("summary",null,"Tags:"),e("a",{href:"/garden/my-projects/index.md"},"My Projects")],-1),u=e("p",null,"A 3D VR re-envisioning of a Slay the Spire-style game by Anthony Lawn and Grant Barbee for their VR class in college's final project.",-1),_=e("p",null,[t("For more details, visit "),e("a",{href:"https://grantcbarbee.github.io/conquer-the-citadel.html",target:"_blank",rel:"noreferrer"},"Grant's page on the game"),t(".")],-1),m=e("div",{class:"img-container"},[e("img",{src:i,title:"screenshot.png"})],-1),C=JSON.parse('{"title":"Capture the Citadel","description":"","frontmatter":{"public":"true","slug":"capture-the-citadel","tags":["My Projects"],"title":"Capture the Citadel","prev":false,"next":false},"headers":[],"relativePath":"garden/capture-the-citadel/index.md","filePath":"garden/capture-the-citadel/index.md"}'),g={name:"garden/capture-the-citadel/index.md"},j=Object.assign(g,{setup(f){const r=s();return(b,v)=>(l(),n("div",null,[c,e("p",null,[t("39 words, ~0 minute read. "),e("span",{innerHTML:a(o)[`site/${a(r).page.value.relativePath}`]},null,8,d)]),p,h,u,_,m]))}});export{C as __pageData,j as default}; diff --git a/assets/garden_capture-the-citadel_index.md.-br6Pcc8.lean.js b/assets/garden_capture-the-citadel_index.md.CiAmkxr4.lean.js similarity index 95% rename from assets/garden_capture-the-citadel_index.md.-br6Pcc8.lean.js rename to assets/garden_capture-the-citadel_index.md.CiAmkxr4.lean.js index 7db2f5cc1..67b9bce78 100644 --- a/assets/garden_capture-the-citadel_index.md.-br6Pcc8.lean.js +++ b/assets/garden_capture-the-citadel_index.md.CiAmkxr4.lean.js @@ -1 +1 @@ -import{M as s,q as n,Q as e,K as t,u as a,ah as i,p as l}from"./chunks/framework.Sr2_9k8k.js";import{d as o}from"./chunks/git.data.D-Ga3RhB.js";const c=e("h1",{class:"p-name"},"Capture the Citadel",-1),d=["innerHTML"],p=e("hr",null,null,-1),h=e("details",null,[e("summary",null,"Tags:"),e("a",{href:"/garden/my-projects/index.md"},"My Projects")],-1),u=e("p",null,"A 3D VR re-envisioning of a Slay the Spire-style game by Anthony Lawn and Grant Barbee for their VR class in college's final project.",-1),_=e("p",null,[t("For more details, visit "),e("a",{href:"https://grantcbarbee.github.io/conquer-the-citadel.html",target:"_blank",rel:"noreferrer"},"Grant's page on the game"),t(".")],-1),m=e("div",{class:"img-container"},[e("img",{src:i,title:"screenshot.png"})],-1),C=JSON.parse('{"title":"Capture the Citadel","description":"","frontmatter":{"public":"true","slug":"capture-the-citadel","tags":["My Projects"],"title":"Capture the Citadel","prev":false,"next":false},"headers":[],"relativePath":"garden/capture-the-citadel/index.md","filePath":"garden/capture-the-citadel/index.md"}'),g={name:"garden/capture-the-citadel/index.md"},j=Object.assign(g,{setup(f){const r=s();return(b,v)=>(l(),n("div",null,[c,e("p",null,[t("39 words, ~0 minute read. "),e("span",{innerHTML:a(o)[`site/${a(r).page.value.relativePath}`]},null,8,d)]),p,h,u,_,m]))}});export{C as __pageData,j as default}; +import{M as s,q as n,Q as e,K as t,u as a,ah as i,p as l}from"./chunks/framework.Sr2_9k8k.js";import{d as o}from"./chunks/git.data.BcrWSzMU.js";const c=e("h1",{class:"p-name"},"Capture the Citadel",-1),d=["innerHTML"],p=e("hr",null,null,-1),h=e("details",null,[e("summary",null,"Tags:"),e("a",{href:"/garden/my-projects/index.md"},"My Projects")],-1),u=e("p",null,"A 3D VR re-envisioning of a Slay the Spire-style game by Anthony Lawn and Grant Barbee for their VR class in college's final project.",-1),_=e("p",null,[t("For more details, visit "),e("a",{href:"https://grantcbarbee.github.io/conquer-the-citadel.html",target:"_blank",rel:"noreferrer"},"Grant's page on the game"),t(".")],-1),m=e("div",{class:"img-container"},[e("img",{src:i,title:"screenshot.png"})],-1),C=JSON.parse('{"title":"Capture the Citadel","description":"","frontmatter":{"public":"true","slug":"capture-the-citadel","tags":["My Projects"],"title":"Capture the Citadel","prev":false,"next":false},"headers":[],"relativePath":"garden/capture-the-citadel/index.md","filePath":"garden/capture-the-citadel/index.md"}'),g={name:"garden/capture-the-citadel/index.md"},j=Object.assign(g,{setup(f){const r=s();return(b,v)=>(l(),n("div",null,[c,e("p",null,[t("39 words, ~0 minute read. "),e("span",{innerHTML:a(o)[`site/${a(r).page.value.relativePath}`]},null,8,d)]),p,h,u,_,m]))}});export{C as __pageData,j as default}; diff --git a/assets/garden_chat-glue_index.md.BFBOFQOt.js b/assets/garden_chat-glue_index.md.BUFDcaM4.js similarity index 94% rename from assets/garden_chat-glue_index.md.BFBOFQOt.js rename to assets/garden_chat-glue_index.md.BUFDcaM4.js index 852ba4873..3fa9eedba 100644 --- a/assets/garden_chat-glue_index.md.BFBOFQOt.js +++ b/assets/garden_chat-glue_index.md.BUFDcaM4.js @@ -1 +1 @@ -import{d as l}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as r,Q as e,K as t,u as a,p as i}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Chat Glue",-1),c=["innerHTML"],d=e("hr",null,null,-1),u=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/commune/index.md"},"Commune"),e("a",{href:"/garden/the-small-web/index.md"},"The Small Web")],-1),h=e("p",null,"A theoretical chat system designed to solve the problems of transcribing branching conversations into linear timelines.",-1),m=e("p",null,[t("Defined by the "),e("a",{href:"https://a9.io/glue-comic/",target:"_blank",rel:"noreferrer"},"Chatting with Glue"),t(" comic.")],-1),v=JSON.parse('{"title":"Chat Glue","description":"","frontmatter":{"public":"true","slug":"chat-glue","title":"Chat Glue","prev":false,"next":false},"headers":[],"relativePath":"garden/chat-glue/index.md","filePath":"garden/chat-glue/index.md"}'),_={name:"garden/chat-glue/index.md"},C=Object.assign(_,{setup(p){const n=s();return(g,f)=>(i(),r("div",null,[o,e("p",null,[t("23 words, ~0 minute read. "),e("span",{innerHTML:a(l)[`site/${a(n).page.value.relativePath}`]},null,8,c)]),d,u,h,m]))}});export{v as __pageData,C as default}; +import{d as l}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as r,Q as e,K as t,u as a,p as i}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Chat Glue",-1),c=["innerHTML"],d=e("hr",null,null,-1),u=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/commune/index.md"},"Commune"),e("a",{href:"/garden/the-small-web/index.md"},"The Small Web")],-1),h=e("p",null,"A theoretical chat system designed to solve the problems of transcribing branching conversations into linear timelines.",-1),m=e("p",null,[t("Defined by the "),e("a",{href:"https://a9.io/glue-comic/",target:"_blank",rel:"noreferrer"},"Chatting with Glue"),t(" comic.")],-1),v=JSON.parse('{"title":"Chat Glue","description":"","frontmatter":{"public":"true","slug":"chat-glue","title":"Chat Glue","prev":false,"next":false},"headers":[],"relativePath":"garden/chat-glue/index.md","filePath":"garden/chat-glue/index.md"}'),_={name:"garden/chat-glue/index.md"},C=Object.assign(_,{setup(p){const n=s();return(g,f)=>(i(),r("div",null,[o,e("p",null,[t("23 words, ~0 minute read. "),e("span",{innerHTML:a(l)[`site/${a(n).page.value.relativePath}`]},null,8,c)]),d,u,h,m]))}});export{v as __pageData,C as default}; diff --git a/assets/garden_chat-glue_index.md.BFBOFQOt.lean.js b/assets/garden_chat-glue_index.md.BUFDcaM4.lean.js similarity index 94% rename from assets/garden_chat-glue_index.md.BFBOFQOt.lean.js rename to assets/garden_chat-glue_index.md.BUFDcaM4.lean.js index 852ba4873..3fa9eedba 100644 --- a/assets/garden_chat-glue_index.md.BFBOFQOt.lean.js +++ b/assets/garden_chat-glue_index.md.BUFDcaM4.lean.js @@ -1 +1 @@ -import{d as l}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as r,Q as e,K as t,u as a,p as i}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Chat Glue",-1),c=["innerHTML"],d=e("hr",null,null,-1),u=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/commune/index.md"},"Commune"),e("a",{href:"/garden/the-small-web/index.md"},"The Small Web")],-1),h=e("p",null,"A theoretical chat system designed to solve the problems of transcribing branching conversations into linear timelines.",-1),m=e("p",null,[t("Defined by the "),e("a",{href:"https://a9.io/glue-comic/",target:"_blank",rel:"noreferrer"},"Chatting with Glue"),t(" comic.")],-1),v=JSON.parse('{"title":"Chat Glue","description":"","frontmatter":{"public":"true","slug":"chat-glue","title":"Chat Glue","prev":false,"next":false},"headers":[],"relativePath":"garden/chat-glue/index.md","filePath":"garden/chat-glue/index.md"}'),_={name:"garden/chat-glue/index.md"},C=Object.assign(_,{setup(p){const n=s();return(g,f)=>(i(),r("div",null,[o,e("p",null,[t("23 words, ~0 minute read. "),e("span",{innerHTML:a(l)[`site/${a(n).page.value.relativePath}`]},null,8,c)]),d,u,h,m]))}});export{v as __pageData,C as default}; +import{d as l}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as r,Q as e,K as t,u as a,p as i}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Chat Glue",-1),c=["innerHTML"],d=e("hr",null,null,-1),u=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/commune/index.md"},"Commune"),e("a",{href:"/garden/the-small-web/index.md"},"The Small Web")],-1),h=e("p",null,"A theoretical chat system designed to solve the problems of transcribing branching conversations into linear timelines.",-1),m=e("p",null,[t("Defined by the "),e("a",{href:"https://a9.io/glue-comic/",target:"_blank",rel:"noreferrer"},"Chatting with Glue"),t(" comic.")],-1),v=JSON.parse('{"title":"Chat Glue","description":"","frontmatter":{"public":"true","slug":"chat-glue","title":"Chat Glue","prev":false,"next":false},"headers":[],"relativePath":"garden/chat-glue/index.md","filePath":"garden/chat-glue/index.md"}'),_={name:"garden/chat-glue/index.md"},C=Object.assign(_,{setup(p){const n=s();return(g,f)=>(i(),r("div",null,[o,e("p",null,[t("23 words, ~0 minute read. "),e("span",{innerHTML:a(l)[`site/${a(n).page.value.relativePath}`]},null,8,c)]),d,u,h,m]))}});export{v as __pageData,C as default}; diff --git a/assets/garden_chromatic-lattice_index.md.Cw8Kko32.js b/assets/garden_chromatic-lattice_index.md.B5qPBo-S.js similarity index 97% rename from assets/garden_chromatic-lattice_index.md.Cw8Kko32.js rename to assets/garden_chromatic-lattice_index.md.B5qPBo-S.js index 37802e56f..2e206e490 100644 --- a/assets/garden_chromatic-lattice_index.md.Cw8Kko32.js +++ b/assets/garden_chromatic-lattice_index.md.B5qPBo-S.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as r,Q as e,K as n,u as a,ag as l,p as s}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Chromatic Lattice",-1),d=["innerHTML"],h=l('
Referenced by:Digital LocalityFedi v2Incremental Social/now

A multiplayer game I have in development. It'll be about optimizing a board of tiles to create certain patterns to improve resource gains. Players will work collaboratively to construct monuments. It will be built on the Agentic Fediverse and experiment with Digital Locality.

A person's board will act as their profile page, and will include a local chat room (in addition to the global one), a description, a list of people currently on the page, and a friends list that can be broken down into categories. Your cursor also appears on the board for all other users, although those can be toggled off in settings.

The friend lists effectively work as the links between nodes, creating locality. Everyone has a link to their own board accessible at all times, and from there to their friends. All links would also show a count of how many people are on that board.

In addition to friends, you can jump to a players board or to wherever the player is by right clicking their name in global chat. You can also share links to your board off platform as well.

',6),b=JSON.parse('{"title":"Chromatic Lattice","description":"","frontmatter":{"public":"true","slug":"chromatic-lattice","title":"Chromatic Lattice","prev":false,"next":false},"headers":[],"relativePath":"garden/chromatic-lattice/index.md","filePath":"garden/chromatic-lattice/index.md"}'),p={name:"garden/chromatic-lattice/index.md"},y=Object.assign(p,{setup(m){const t=o();return(f,u)=>(s(),r("div",null,[c,e("p",null,[n("189 words, ~1 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),h]))}});export{b as __pageData,y as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as r,Q as e,K as n,u as a,ag as l,p as s}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Chromatic Lattice",-1),d=["innerHTML"],h=l('
Referenced by:Digital LocalityFedi v2Incremental Social/now

A multiplayer game I have in development. It'll be about optimizing a board of tiles to create certain patterns to improve resource gains. Players will work collaboratively to construct monuments. It will be built on the Agentic Fediverse and experiment with Digital Locality.

A person's board will act as their profile page, and will include a local chat room (in addition to the global one), a description, a list of people currently on the page, and a friends list that can be broken down into categories. Your cursor also appears on the board for all other users, although those can be toggled off in settings.

The friend lists effectively work as the links between nodes, creating locality. Everyone has a link to their own board accessible at all times, and from there to their friends. All links would also show a count of how many people are on that board.

In addition to friends, you can jump to a players board or to wherever the player is by right clicking their name in global chat. You can also share links to your board off platform as well.

',6),b=JSON.parse('{"title":"Chromatic Lattice","description":"","frontmatter":{"public":"true","slug":"chromatic-lattice","title":"Chromatic Lattice","prev":false,"next":false},"headers":[],"relativePath":"garden/chromatic-lattice/index.md","filePath":"garden/chromatic-lattice/index.md"}'),p={name:"garden/chromatic-lattice/index.md"},y=Object.assign(p,{setup(m){const t=o();return(f,u)=>(s(),r("div",null,[c,e("p",null,[n("189 words, ~1 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),h]))}});export{b as __pageData,y as default}; diff --git a/assets/garden_chromatic-lattice_index.md.Cw8Kko32.lean.js b/assets/garden_chromatic-lattice_index.md.B5qPBo-S.lean.js similarity index 92% rename from assets/garden_chromatic-lattice_index.md.Cw8Kko32.lean.js rename to assets/garden_chromatic-lattice_index.md.B5qPBo-S.lean.js index 210f4cfcf..461f86a2e 100644 --- a/assets/garden_chromatic-lattice_index.md.Cw8Kko32.lean.js +++ b/assets/garden_chromatic-lattice_index.md.B5qPBo-S.lean.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as r,Q as e,K as n,u as a,ag as l,p as s}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Chromatic Lattice",-1),d=["innerHTML"],h=l("",6),b=JSON.parse('{"title":"Chromatic Lattice","description":"","frontmatter":{"public":"true","slug":"chromatic-lattice","title":"Chromatic Lattice","prev":false,"next":false},"headers":[],"relativePath":"garden/chromatic-lattice/index.md","filePath":"garden/chromatic-lattice/index.md"}'),p={name:"garden/chromatic-lattice/index.md"},y=Object.assign(p,{setup(m){const t=o();return(f,u)=>(s(),r("div",null,[c,e("p",null,[n("189 words, ~1 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),h]))}});export{b as __pageData,y as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as r,Q as e,K as n,u as a,ag as l,p as s}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Chromatic Lattice",-1),d=["innerHTML"],h=l("",6),b=JSON.parse('{"title":"Chromatic Lattice","description":"","frontmatter":{"public":"true","slug":"chromatic-lattice","title":"Chromatic Lattice","prev":false,"next":false},"headers":[],"relativePath":"garden/chromatic-lattice/index.md","filePath":"garden/chromatic-lattice/index.md"}'),p={name:"garden/chromatic-lattice/index.md"},y=Object.assign(p,{setup(m){const t=o();return(f,u)=>(s(),r("div",null,[c,e("p",null,[n("189 words, ~1 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),h]))}});export{b as __pageData,y as default}; diff --git a/assets/garden_chronological_index.md.D5fWpnlX.js b/assets/garden_chronological_index.md.Zheg5VVb.js similarity index 96% rename from assets/garden_chronological_index.md.D5fWpnlX.js rename to assets/garden_chronological_index.md.Zheg5VVb.js index 0597abf49..233eebd4d 100644 --- a/assets/garden_chronological_index.md.D5fWpnlX.js +++ b/assets/garden_chronological_index.md.Zheg5VVb.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as r,q as i,Q as e,K as n,u as a,ag as l,p as s}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Chronological",-1),d=["innerHTML"],h=l('
Referenced by:Digital GardensFreeform vs Chronological Dichotomy

A collection of information that is tied to its creation or edit date

Part of the Freeform vs Chronological Dichotomy

Anything with a "timeline" or "feed" is considered chronological

  • Even if there's algorithmic sortings that take things other than creation or edit date into account!

Chronological displays are less suitable as stores of knowledge (Digital Gardens)

Social media overuses timelines and feeds

RSS feeds work really well with this form of content

',9),v=JSON.parse('{"title":"Chronological","description":"","frontmatter":{"public":"true","slug":"chronological","title":"Chronological","prev":false,"next":false},"headers":[],"relativePath":"garden/chronological/index.md","filePath":"garden/chronological/index.md"}'),g={name:"garden/chronological/index.md"},y=Object.assign(g,{setup(m){const o=r();return(f,p)=>(s(),i("div",null,[c,e("p",null,[n("73 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(o).page.value.relativePath}`]},null,8,d)]),h]))}});export{v as __pageData,y as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as r,q as i,Q as e,K as n,u as a,ag as l,p as s}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Chronological",-1),d=["innerHTML"],h=l('
Referenced by:Digital GardensFreeform vs Chronological Dichotomy

A collection of information that is tied to its creation or edit date

Part of the Freeform vs Chronological Dichotomy

Anything with a "timeline" or "feed" is considered chronological

  • Even if there's algorithmic sortings that take things other than creation or edit date into account!

Chronological displays are less suitable as stores of knowledge (Digital Gardens)

Social media overuses timelines and feeds

RSS feeds work really well with this form of content

',9),v=JSON.parse('{"title":"Chronological","description":"","frontmatter":{"public":"true","slug":"chronological","title":"Chronological","prev":false,"next":false},"headers":[],"relativePath":"garden/chronological/index.md","filePath":"garden/chronological/index.md"}'),g={name:"garden/chronological/index.md"},y=Object.assign(g,{setup(m){const o=r();return(f,p)=>(s(),i("div",null,[c,e("p",null,[n("73 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(o).page.value.relativePath}`]},null,8,d)]),h]))}});export{v as __pageData,y as default}; diff --git a/assets/garden_chronological_index.md.D5fWpnlX.lean.js b/assets/garden_chronological_index.md.Zheg5VVb.lean.js similarity index 91% rename from assets/garden_chronological_index.md.D5fWpnlX.lean.js rename to assets/garden_chronological_index.md.Zheg5VVb.lean.js index 17fc527ac..79950c840 100644 --- a/assets/garden_chronological_index.md.D5fWpnlX.lean.js +++ b/assets/garden_chronological_index.md.Zheg5VVb.lean.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as r,q as i,Q as e,K as n,u as a,ag as l,p as s}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Chronological",-1),d=["innerHTML"],h=l("",9),v=JSON.parse('{"title":"Chronological","description":"","frontmatter":{"public":"true","slug":"chronological","title":"Chronological","prev":false,"next":false},"headers":[],"relativePath":"garden/chronological/index.md","filePath":"garden/chronological/index.md"}'),g={name:"garden/chronological/index.md"},y=Object.assign(g,{setup(m){const o=r();return(f,p)=>(s(),i("div",null,[c,e("p",null,[n("73 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(o).page.value.relativePath}`]},null,8,d)]),h]))}});export{v as __pageData,y as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as r,q as i,Q as e,K as n,u as a,ag as l,p as s}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Chronological",-1),d=["innerHTML"],h=l("",9),v=JSON.parse('{"title":"Chronological","description":"","frontmatter":{"public":"true","slug":"chronological","title":"Chronological","prev":false,"next":false},"headers":[],"relativePath":"garden/chronological/index.md","filePath":"garden/chronological/index.md"}'),g={name:"garden/chronological/index.md"},y=Object.assign(g,{setup(m){const o=r();return(f,p)=>(s(),i("div",null,[c,e("p",null,[n("73 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(o).page.value.relativePath}`]},null,8,d)]),h]))}});export{v as __pageData,y as default}; diff --git a/assets/garden_cinny_index.md.CWxQ-zXy.js b/assets/garden_cinny_index.md.CKXJ1bbs.js similarity index 94% rename from assets/garden_cinny_index.md.CWxQ-zXy.js rename to assets/garden_cinny_index.md.CKXJ1bbs.js index ddcd7cac5..82429a2f2 100644 --- a/assets/garden_cinny_index.md.CWxQ-zXy.js +++ b/assets/garden_cinny_index.md.CKXJ1bbs.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as i,Q as e,K as n,u as a,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Cinny",-1),c=["innerHTML"],d=e("hr",null,null,-1),u=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social")],-1),p=e("p",null,[e("a",{href:"https://cinny.in",target:"_blank",rel:"noreferrer"},"Cinny"),n(" is an "),e("a",{href:"/garden/open-source/"},"Open Source"),n(" web client for the "),e("a",{href:"/garden/matrix/"},"Matrix"),n(" messaging protocol")],-1),x=JSON.parse('{"title":"Cinny","description":"","frontmatter":{"public":"true","slug":"cinny","title":"Cinny","prev":false,"next":false},"headers":[],"relativePath":"garden/cinny/index.md","filePath":"garden/cinny/index.md"}'),_={name:"garden/cinny/index.md"},b=Object.assign(_,{setup(m){const t=s();return(h,f)=>(l(),i("div",null,[o,e("p",null,[n("3 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),d,u,p]))}});export{x as __pageData,b as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as i,Q as e,K as n,u as a,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Cinny",-1),c=["innerHTML"],d=e("hr",null,null,-1),u=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social")],-1),p=e("p",null,[e("a",{href:"https://cinny.in",target:"_blank",rel:"noreferrer"},"Cinny"),n(" is an "),e("a",{href:"/garden/open-source/"},"Open Source"),n(" web client for the "),e("a",{href:"/garden/matrix/"},"Matrix"),n(" messaging protocol")],-1),x=JSON.parse('{"title":"Cinny","description":"","frontmatter":{"public":"true","slug":"cinny","title":"Cinny","prev":false,"next":false},"headers":[],"relativePath":"garden/cinny/index.md","filePath":"garden/cinny/index.md"}'),_={name:"garden/cinny/index.md"},b=Object.assign(_,{setup(m){const t=s();return(h,f)=>(l(),i("div",null,[o,e("p",null,[n("3 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),d,u,p]))}});export{x as __pageData,b as default}; diff --git a/assets/garden_cinny_index.md.CWxQ-zXy.lean.js b/assets/garden_cinny_index.md.CKXJ1bbs.lean.js similarity index 94% rename from assets/garden_cinny_index.md.CWxQ-zXy.lean.js rename to assets/garden_cinny_index.md.CKXJ1bbs.lean.js index ddcd7cac5..82429a2f2 100644 --- a/assets/garden_cinny_index.md.CWxQ-zXy.lean.js +++ b/assets/garden_cinny_index.md.CKXJ1bbs.lean.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as i,Q as e,K as n,u as a,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Cinny",-1),c=["innerHTML"],d=e("hr",null,null,-1),u=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social")],-1),p=e("p",null,[e("a",{href:"https://cinny.in",target:"_blank",rel:"noreferrer"},"Cinny"),n(" is an "),e("a",{href:"/garden/open-source/"},"Open Source"),n(" web client for the "),e("a",{href:"/garden/matrix/"},"Matrix"),n(" messaging protocol")],-1),x=JSON.parse('{"title":"Cinny","description":"","frontmatter":{"public":"true","slug":"cinny","title":"Cinny","prev":false,"next":false},"headers":[],"relativePath":"garden/cinny/index.md","filePath":"garden/cinny/index.md"}'),_={name:"garden/cinny/index.md"},b=Object.assign(_,{setup(m){const t=s();return(h,f)=>(l(),i("div",null,[o,e("p",null,[n("3 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),d,u,p]))}});export{x as __pageData,b as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as i,Q as e,K as n,u as a,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Cinny",-1),c=["innerHTML"],d=e("hr",null,null,-1),u=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social")],-1),p=e("p",null,[e("a",{href:"https://cinny.in",target:"_blank",rel:"noreferrer"},"Cinny"),n(" is an "),e("a",{href:"/garden/open-source/"},"Open Source"),n(" web client for the "),e("a",{href:"/garden/matrix/"},"Matrix"),n(" messaging protocol")],-1),x=JSON.parse('{"title":"Cinny","description":"","frontmatter":{"public":"true","slug":"cinny","title":"Cinny","prev":false,"next":false},"headers":[],"relativePath":"garden/cinny/index.md","filePath":"garden/cinny/index.md"}'),_={name:"garden/cinny/index.md"},b=Object.assign(_,{setup(m){const t=s();return(h,f)=>(l(),i("div",null,[o,e("p",null,[n("3 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),d,u,p]))}});export{x as __pageData,b as default}; diff --git a/assets/garden_command-palettes_index.md.CTOBvuQi.js b/assets/garden_command-palettes_index.md.DPkTiZSA.js similarity index 96% rename from assets/garden_command-palettes_index.md.CTOBvuQi.js rename to assets/garden_command-palettes_index.md.DPkTiZSA.js index b5f69f592..771007828 100644 --- a/assets/garden_command-palettes_index.md.CTOBvuQi.js +++ b/assets/garden_command-palettes_index.md.DPkTiZSA.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as l,Q as e,K as i,u as a,ag as o,p as r}from"./chunks/framework.Sr2_9k8k.js";const m=e("h1",{class:"p-name"},"Command Palettes",-1),c=["innerHTML"],p=o('

Command palettes are a design pattern where apps expose functionality through a search bar

Typing what you want is almost certainly easier and faster than finding the action in some submenu or remembering an arcane hotkey

  • Especially with fuzzy search that also looks through descriptions of actions
  • Command palettes scale very well with large amounts of actions

Artificial Intelligence will make command palettes increasingly powerful

  • Eventually these may become conversational interfaces

Maggie Appleton discusses this pattern in her article on Command K Bars

  • The name comes from the fact many apps use the ctrl/cmd k shortcut to open the command palette

Many softwares I use have some form of command palette

  • Linear
  • Logseq
  • Visual Studio Code
',10),y=JSON.parse('{"title":"Command Palettes","description":"","frontmatter":{"public":"true","slug":"command-palettes","title":"Command Palettes","prev":false,"next":false},"headers":[],"relativePath":"garden/command-palettes/index.md","filePath":"garden/command-palettes/index.md"}'),d={name:"garden/command-palettes/index.md"},T=Object.assign(d,{setup(u){const t=s();return(h,_)=>(r(),l("div",null,[m,e("p",null,[i("117 words, ~1 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),p]))}});export{y as __pageData,T as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as l,Q as e,K as i,u as a,ag as o,p as r}from"./chunks/framework.Sr2_9k8k.js";const m=e("h1",{class:"p-name"},"Command Palettes",-1),c=["innerHTML"],p=o('

Command palettes are a design pattern where apps expose functionality through a search bar

Typing what you want is almost certainly easier and faster than finding the action in some submenu or remembering an arcane hotkey

  • Especially with fuzzy search that also looks through descriptions of actions
  • Command palettes scale very well with large amounts of actions

Artificial Intelligence will make command palettes increasingly powerful

  • Eventually these may become conversational interfaces

Maggie Appleton discusses this pattern in her article on Command K Bars

  • The name comes from the fact many apps use the ctrl/cmd k shortcut to open the command palette

Many softwares I use have some form of command palette

  • Linear
  • Logseq
  • Visual Studio Code
',10),y=JSON.parse('{"title":"Command Palettes","description":"","frontmatter":{"public":"true","slug":"command-palettes","title":"Command Palettes","prev":false,"next":false},"headers":[],"relativePath":"garden/command-palettes/index.md","filePath":"garden/command-palettes/index.md"}'),d={name:"garden/command-palettes/index.md"},T=Object.assign(d,{setup(u){const t=s();return(h,_)=>(r(),l("div",null,[m,e("p",null,[i("117 words, ~1 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),p]))}});export{y as __pageData,T as default}; diff --git a/assets/garden_command-palettes_index.md.CTOBvuQi.lean.js b/assets/garden_command-palettes_index.md.DPkTiZSA.lean.js similarity index 91% rename from assets/garden_command-palettes_index.md.CTOBvuQi.lean.js rename to assets/garden_command-palettes_index.md.DPkTiZSA.lean.js index 7913647cf..bda7a2ecc 100644 --- a/assets/garden_command-palettes_index.md.CTOBvuQi.lean.js +++ b/assets/garden_command-palettes_index.md.DPkTiZSA.lean.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as l,Q as e,K as i,u as a,ag as o,p as r}from"./chunks/framework.Sr2_9k8k.js";const m=e("h1",{class:"p-name"},"Command Palettes",-1),c=["innerHTML"],p=o("",10),y=JSON.parse('{"title":"Command Palettes","description":"","frontmatter":{"public":"true","slug":"command-palettes","title":"Command Palettes","prev":false,"next":false},"headers":[],"relativePath":"garden/command-palettes/index.md","filePath":"garden/command-palettes/index.md"}'),d={name:"garden/command-palettes/index.md"},T=Object.assign(d,{setup(u){const t=s();return(h,_)=>(r(),l("div",null,[m,e("p",null,[i("117 words, ~1 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),p]))}});export{y as __pageData,T as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as l,Q as e,K as i,u as a,ag as o,p as r}from"./chunks/framework.Sr2_9k8k.js";const m=e("h1",{class:"p-name"},"Command Palettes",-1),c=["innerHTML"],p=o("",10),y=JSON.parse('{"title":"Command Palettes","description":"","frontmatter":{"public":"true","slug":"command-palettes","title":"Command Palettes","prev":false,"next":false},"headers":[],"relativePath":"garden/command-palettes/index.md","filePath":"garden/command-palettes/index.md"}'),d={name:"garden/command-palettes/index.md"},T=Object.assign(d,{setup(u){const t=s();return(h,_)=>(r(),l("div",null,[m,e("p",null,[i("117 words, ~1 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),p]))}});export{y as __pageData,T as default}; diff --git a/assets/garden_commune_index.md.COmv47Qq.js b/assets/garden_commune_index.md.CoCiInjd.js similarity index 97% rename from assets/garden_commune_index.md.COmv47Qq.js rename to assets/garden_commune_index.md.CoCiInjd.js index 37243327d..945d19b06 100644 --- a/assets/garden_commune_index.md.COmv47Qq.js +++ b/assets/garden_commune_index.md.CoCiInjd.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as l,Q as e,K as n,u as a,ag as s,p as d}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Commune",-1),m=["innerHTML"],h=s('
Referenced by:Digital LocalityFilter BubblesOrchardWebringsWeird

An Open Source Matrix web client built to be better for communities than anything else out there

  • Currently in development
  • Exposes certain channels such that they are web indexable
  • Will include features like Chat Glue and communal Digital Gardens

Created by Erlend Sogge Heggen, a ex-employee from Discourse

  • Maintains the Commune Blog with great write ups on the issues of the modern web, social media, etc. and how they can be improved (by Commune or related projects)
  • Also maintains a Personal Blog about similar topics

The Commune community is very interested in various topics and how they can relate together:

Related projects:

  • @laxla@tech.lgbt is creating Gimli, a federated discord alternative
    • Built on ActivityPub
    • "Guild-based" in ways matrix is not?
    • Will integrate with F3 as well
    • Wants to handle blogging as well
    • Certainly seems similar to Commune's message gardening concept
',10),_=JSON.parse('{"title":"Commune","description":"","frontmatter":{"public":"true","slug":"commune","title":"Commune","prev":false,"next":false},"headers":[],"relativePath":"garden/commune/index.md","filePath":"garden/commune/index.md"}'),c={name:"garden/commune/index.md"},y=Object.assign(c,{setup(u){const r=i();return(g,f)=>(d(),l("div",null,[o,e("p",null,[n("144 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,m)]),h]))}});export{_ as __pageData,y as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as l,Q as e,K as n,u as a,ag as s,p as d}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Commune",-1),m=["innerHTML"],h=s('
Referenced by:Digital LocalityFilter BubblesOrchardWebringsWeird

An Open Source Matrix web client built to be better for communities than anything else out there

  • Currently in development
  • Exposes certain channels such that they are web indexable
  • Will include features like Chat Glue and communal Digital Gardens

Created by Erlend Sogge Heggen, a ex-employee from Discourse

  • Maintains the Commune Blog with great write ups on the issues of the modern web, social media, etc. and how they can be improved (by Commune or related projects)
  • Also maintains a Personal Blog about similar topics

The Commune community is very interested in various topics and how they can relate together:

Related projects:

  • @laxla@tech.lgbt is creating Gimli, a federated discord alternative
    • Built on ActivityPub
    • "Guild-based" in ways matrix is not?
    • Will integrate with F3 as well
    • Wants to handle blogging as well
    • Certainly seems similar to Commune's message gardening concept
',10),_=JSON.parse('{"title":"Commune","description":"","frontmatter":{"public":"true","slug":"commune","title":"Commune","prev":false,"next":false},"headers":[],"relativePath":"garden/commune/index.md","filePath":"garden/commune/index.md"}'),c={name:"garden/commune/index.md"},y=Object.assign(c,{setup(u){const r=i();return(g,f)=>(d(),l("div",null,[o,e("p",null,[n("144 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,m)]),h]))}});export{_ as __pageData,y as default}; diff --git a/assets/garden_commune_index.md.COmv47Qq.lean.js b/assets/garden_commune_index.md.CoCiInjd.lean.js similarity index 91% rename from assets/garden_commune_index.md.COmv47Qq.lean.js rename to assets/garden_commune_index.md.CoCiInjd.lean.js index 45b99e7bb..40373d52b 100644 --- a/assets/garden_commune_index.md.COmv47Qq.lean.js +++ b/assets/garden_commune_index.md.CoCiInjd.lean.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as l,Q as e,K as n,u as a,ag as s,p as d}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Commune",-1),m=["innerHTML"],h=s("",10),_=JSON.parse('{"title":"Commune","description":"","frontmatter":{"public":"true","slug":"commune","title":"Commune","prev":false,"next":false},"headers":[],"relativePath":"garden/commune/index.md","filePath":"garden/commune/index.md"}'),c={name:"garden/commune/index.md"},y=Object.assign(c,{setup(u){const r=i();return(g,f)=>(d(),l("div",null,[o,e("p",null,[n("144 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,m)]),h]))}});export{_ as __pageData,y as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as l,Q as e,K as n,u as a,ag as s,p as d}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Commune",-1),m=["innerHTML"],h=s("",10),_=JSON.parse('{"title":"Commune","description":"","frontmatter":{"public":"true","slug":"commune","title":"Commune","prev":false,"next":false},"headers":[],"relativePath":"garden/commune/index.md","filePath":"garden/commune/index.md"}'),c={name:"garden/commune/index.md"},y=Object.assign(c,{setup(u){const r=i();return(g,f)=>(d(),l("div",null,[o,e("p",null,[n("144 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,m)]),h]))}});export{_ as __pageData,y as default}; diff --git a/assets/garden_consensus-democracy_index.md.DiXMmLIQ.js b/assets/garden_consensus-democracy_index.md.CofuRdBH.js similarity index 97% rename from assets/garden_consensus-democracy_index.md.DiXMmLIQ.js rename to assets/garden_consensus-democracy_index.md.CofuRdBH.js index 0f0ef50e6..ec0679cde 100644 --- a/assets/garden_consensus-democracy_index.md.DiXMmLIQ.js +++ b/assets/garden_consensus-democracy_index.md.CofuRdBH.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as r,Q as e,K as i,u as a,ag as n,p as c}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Consensus Democracy",-1),d=["innerHTML"],m=n('
Referenced by:AnarchismGerrymanderingMy Political Beliefs

A form of democracy similar to Direct Democracy but with higher requirements for passing policies, typically requiring unanimity or near-unanimity. This helps reduce (although doesn't eliminate) the possibility of a majority group oppressing a minority group.

Consensus democracy encourages and requires innovative solutions to problems (similar to Police Abolition) and pragmatic compromises. However, this can make them susceptible to "design by committee" and can make policies impossibly difficult to pass for large groups of people.

Since consensus democracy doesn't scale well, larger governments could be structured as a federation of smaller governments. The smaller governments still use consensus democracy, but the federation only adopts policies that a super-majority of the smaller governments have agreed upon. Alternatively, the federation could specifically ask the local governments for policy proposals, then use Direct Democracy to decide whether to approve it or not, still requiring a super-majority.

For policies that still are unable to pass federally, local governments could form coalitions that organize larger-scale initiatives between several districts where there is consensus support. For example, this could empower efforts like transit systems between districts. These coalitions could possibly end up making the federal level obsolete, and ensure people are still only subject to laws and policies that made it through consensus.

Transitioning to a direct democracy will face difficulties in finding an initial set of rules that people can agree with.

',7),_=JSON.parse('{"title":"Consensus Democracy","description":"","frontmatter":{"public":"true","slug":"consensus-democracy","title":"Consensus Democracy","prev":false,"next":false},"headers":[],"relativePath":"garden/consensus-democracy/index.md","filePath":"garden/consensus-democracy/index.md"}'),p={name:"garden/consensus-democracy/index.md"},b=Object.assign(p,{setup(u){const s=o();return(h,g)=>(c(),r("div",null,[l,e("p",null,[i("213 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(s).page.value.relativePath}`]},null,8,d)]),m]))}});export{_ as __pageData,b as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as r,Q as e,K as i,u as a,ag as n,p as c}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Consensus Democracy",-1),d=["innerHTML"],m=n('
Referenced by:AnarchismGerrymanderingMy Political Beliefs

A form of democracy similar to Direct Democracy but with higher requirements for passing policies, typically requiring unanimity or near-unanimity. This helps reduce (although doesn't eliminate) the possibility of a majority group oppressing a minority group.

Consensus democracy encourages and requires innovative solutions to problems (similar to Police Abolition) and pragmatic compromises. However, this can make them susceptible to "design by committee" and can make policies impossibly difficult to pass for large groups of people.

Since consensus democracy doesn't scale well, larger governments could be structured as a federation of smaller governments. The smaller governments still use consensus democracy, but the federation only adopts policies that a super-majority of the smaller governments have agreed upon. Alternatively, the federation could specifically ask the local governments for policy proposals, then use Direct Democracy to decide whether to approve it or not, still requiring a super-majority.

For policies that still are unable to pass federally, local governments could form coalitions that organize larger-scale initiatives between several districts where there is consensus support. For example, this could empower efforts like transit systems between districts. These coalitions could possibly end up making the federal level obsolete, and ensure people are still only subject to laws and policies that made it through consensus.

Transitioning to a direct democracy will face difficulties in finding an initial set of rules that people can agree with.

',7),_=JSON.parse('{"title":"Consensus Democracy","description":"","frontmatter":{"public":"true","slug":"consensus-democracy","title":"Consensus Democracy","prev":false,"next":false},"headers":[],"relativePath":"garden/consensus-democracy/index.md","filePath":"garden/consensus-democracy/index.md"}'),p={name:"garden/consensus-democracy/index.md"},b=Object.assign(p,{setup(u){const s=o();return(h,g)=>(c(),r("div",null,[l,e("p",null,[i("213 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(s).page.value.relativePath}`]},null,8,d)]),m]))}});export{_ as __pageData,b as default}; diff --git a/assets/garden_consensus-democracy_index.md.DiXMmLIQ.lean.js b/assets/garden_consensus-democracy_index.md.CofuRdBH.lean.js similarity index 92% rename from assets/garden_consensus-democracy_index.md.DiXMmLIQ.lean.js rename to assets/garden_consensus-democracy_index.md.CofuRdBH.lean.js index 6550331ad..4e071067a 100644 --- a/assets/garden_consensus-democracy_index.md.DiXMmLIQ.lean.js +++ b/assets/garden_consensus-democracy_index.md.CofuRdBH.lean.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as r,Q as e,K as i,u as a,ag as n,p as c}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Consensus Democracy",-1),d=["innerHTML"],m=n("",7),_=JSON.parse('{"title":"Consensus Democracy","description":"","frontmatter":{"public":"true","slug":"consensus-democracy","title":"Consensus Democracy","prev":false,"next":false},"headers":[],"relativePath":"garden/consensus-democracy/index.md","filePath":"garden/consensus-democracy/index.md"}'),p={name:"garden/consensus-democracy/index.md"},b=Object.assign(p,{setup(u){const s=o();return(h,g)=>(c(),r("div",null,[l,e("p",null,[i("213 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(s).page.value.relativePath}`]},null,8,d)]),m]))}});export{_ as __pageData,b as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as r,Q as e,K as i,u as a,ag as n,p as c}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Consensus Democracy",-1),d=["innerHTML"],m=n("",7),_=JSON.parse('{"title":"Consensus Democracy","description":"","frontmatter":{"public":"true","slug":"consensus-democracy","title":"Consensus Democracy","prev":false,"next":false},"headers":[],"relativePath":"garden/consensus-democracy/index.md","filePath":"garden/consensus-democracy/index.md"}'),p={name:"garden/consensus-democracy/index.md"},b=Object.assign(p,{setup(u){const s=o();return(h,g)=>(c(),r("div",null,[l,e("p",null,[i("213 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(s).page.value.relativePath}`]},null,8,d)]),m]))}});export{_ as __pageData,b as default}; diff --git a/assets/garden_davey-wreden_index.md.f3xZ_s4l.js b/assets/garden_davey-wreden_index.md.gXQRuuUm.js similarity index 96% rename from assets/garden_davey-wreden_index.md.f3xZ_s4l.js rename to assets/garden_davey-wreden_index.md.gXQRuuUm.js index 8e91040ed..313a021a8 100644 --- a/assets/garden_davey-wreden_index.md.f3xZ_s4l.js +++ b/assets/garden_davey-wreden_index.md.gXQRuuUm.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as t,q as d,Q as e,K as i,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Davey Wreden",-1),h=["innerHTML"],u=s('
Referenced by:Ivy RoadThe Beginner's Guide
Tagged by:Ivy RoadThe Beginner's GuideWanderstop

Projects:

Talks and Interviews:

',7),v=JSON.parse('{"title":"Davey Wreden","description":"","frontmatter":{"public":"true","slug":"davey-wreden","title":"Davey Wreden","prev":false,"next":false},"headers":[],"relativePath":"garden/davey-wreden/index.md","filePath":"garden/davey-wreden/index.md"}'),g={name:"garden/davey-wreden/index.md"},f=Object.assign(g,{setup(_){const r=t();return(m,c)=>(l(),d("div",null,[o,e("p",null,[i("37 words, ~0 minute read. "),e("span",{innerHTML:a(n)[`site/${a(r).page.value.relativePath}`]},null,8,h)]),u]))}});export{v as __pageData,f as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as t,q as d,Q as e,K as i,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Davey Wreden",-1),h=["innerHTML"],u=s('
Referenced by:Ivy RoadThe Beginner's Guide
Tagged by:Ivy RoadThe Beginner's GuideWanderstop

Projects:

Talks and Interviews:

',7),v=JSON.parse('{"title":"Davey Wreden","description":"","frontmatter":{"public":"true","slug":"davey-wreden","title":"Davey Wreden","prev":false,"next":false},"headers":[],"relativePath":"garden/davey-wreden/index.md","filePath":"garden/davey-wreden/index.md"}'),g={name:"garden/davey-wreden/index.md"},f=Object.assign(g,{setup(_){const r=t();return(m,c)=>(l(),d("div",null,[o,e("p",null,[i("37 words, ~0 minute read. "),e("span",{innerHTML:a(n)[`site/${a(r).page.value.relativePath}`]},null,8,h)]),u]))}});export{v as __pageData,f as default}; diff --git a/assets/garden_davey-wreden_index.md.f3xZ_s4l.lean.js b/assets/garden_davey-wreden_index.md.gXQRuuUm.lean.js similarity index 91% rename from assets/garden_davey-wreden_index.md.f3xZ_s4l.lean.js rename to assets/garden_davey-wreden_index.md.gXQRuuUm.lean.js index d1bac0a2d..19e98be74 100644 --- a/assets/garden_davey-wreden_index.md.f3xZ_s4l.lean.js +++ b/assets/garden_davey-wreden_index.md.gXQRuuUm.lean.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as t,q as d,Q as e,K as i,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Davey Wreden",-1),h=["innerHTML"],u=s("",7),v=JSON.parse('{"title":"Davey Wreden","description":"","frontmatter":{"public":"true","slug":"davey-wreden","title":"Davey Wreden","prev":false,"next":false},"headers":[],"relativePath":"garden/davey-wreden/index.md","filePath":"garden/davey-wreden/index.md"}'),g={name:"garden/davey-wreden/index.md"},f=Object.assign(g,{setup(_){const r=t();return(m,c)=>(l(),d("div",null,[o,e("p",null,[i("37 words, ~0 minute read. "),e("span",{innerHTML:a(n)[`site/${a(r).page.value.relativePath}`]},null,8,h)]),u]))}});export{v as __pageData,f as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as t,q as d,Q as e,K as i,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Davey Wreden",-1),h=["innerHTML"],u=s("",7),v=JSON.parse('{"title":"Davey Wreden","description":"","frontmatter":{"public":"true","slug":"davey-wreden","title":"Davey Wreden","prev":false,"next":false},"headers":[],"relativePath":"garden/davey-wreden/index.md","filePath":"garden/davey-wreden/index.md"}'),g={name:"garden/davey-wreden/index.md"},f=Object.assign(g,{setup(_){const r=t();return(m,c)=>(l(),d("div",null,[o,e("p",null,[i("37 words, ~0 minute read. "),e("span",{innerHTML:a(n)[`site/${a(r).page.value.relativePath}`]},null,8,h)]),u]))}});export{v as __pageData,f as default}; diff --git a/assets/garden_debate_index.md.DcD9KhbD.js b/assets/garden_debate_index.md.KJcHmWUU.js similarity index 99% rename from assets/garden_debate_index.md.DcD9KhbD.js rename to assets/garden_debate_index.md.KJcHmWUU.js index 09050def8..4e8efc238 100644 --- a/assets/garden_debate_index.md.DcD9KhbD.js +++ b/assets/garden_debate_index.md.KJcHmWUU.js @@ -1 +1 @@ -import{d as o}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as n,Q as e,K as r,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Debate",-1),d=["innerHTML"],u=s('
Referenced by:"No Politics" Rules

Debate takes many forms, but for this article we're going to group them into three categories, and argue why none of them work towards actually finding the best solution to a problem. These categories are going to be structured debates, public debates, and conversational debates.

Structured debates

These are the formal debates held in academic contexts and tournaments. These have predefined formats like Lincoln-Douglas or Oxford style, and have the explicit goal of one of the individuals being judged as the winner not based on having the correct stance or even making good arguments, but for their performance in the debate, dictated by their charisma and rhetoric and ability to respond quickly.

While specific formats vary, many of these debates are filled with gish galloping and other rhetorical flourishes. Gish galloping is when a debater speeds through many arguments with the goal of overwhelming the adversary, as its easier and faster to make unsubstantiated claims than it is to contest them. This is a common technique not just in structured debates but all debates. If you're ever watched Ben Shapiro debate (and you have my sympathies), you've seen the gish gallop technique in action.

These debates are adversarial by design, and there is no opportunity for constructive discussion aimed at arriving at the correct conclusion. The people participating in these debates certainly prepare greatly for arguing their positions, but additionally learn a great many skills and techniques unique to the formal debate format.

It should likely go without saying, but this is clearly not meant to be how new ideas are formed or how solutions get created. This is an academic exercise completely divorced from actually solving the problems in our society. The debates are not intended to influence people or impact policy. The skills developed here do not translate to collaborative problem-solving environments.

Public debates

Public debates are debates held by public figures, such as the presidential debates or debates involving political pundits like Ben Shapiro or Cenk Uyghur. They don't have judges or formal winners and losers. Similar to structured debates, these are adversarial debates that don't aim to form a consensus by the end of the debate. Instead, the goal here is for each debater to improve public sentiment towards themselves.

Gish galloping and its companion reverse gish galloping, whereby a flaw in one specific point is used to dismiss the entire argument, are commonly used here, alongside ad hominem attacks and other fallacies. Since the goal is to change public perception, appeals to emotion work greatly here.

As before, these are not intended to change the minds of either participant. They may influence the audience to view a participant or their position more favorably, but this isn't some victory for the "free market of ideas" - the influence is still tied more to the participants' charisma and rhetorical skill rather than the correctness of their position. Several on the left have argued against the utility of these debates, debate culture, and "debate bro" influencers, such as Wisecrack and Noah Samsen.

Conversational debates

This refers to impromptu political discourse, and typically happens between non-influencers on social media. Its debate for the rest of us! Since this is inherently informal there's no enforced structure, but typically they're adversarial since the conversation starts by someone taking issue with something someone else said.

As with the other types, being adversarial means closing one's mind and framing the debate as a competition with a winner and a loser rather than a constructive conversation building towards consensus. One's ego gets intertwined with being correct, and conceding points becomes akin to admitting personal failures.

Being conversational, participants can come and go and anyone can try initiating arguments. This gives rise to sealioning, a form of bad faith debater that exhausts others with their continuous requests for citations or other responses under the pretense of civility. While they can be grating on anyone, their especially a problem for influencers or those who "go viral". The issue is the sheer amount of criticism, the mental and emotional drain filtering through it can be, and the nebulousness of what even is "valid criticism". Innuendo Studios discussed this concept in Why Don't You Respond to Criticism?.

Alternatives to debate

Improving your understanding

If you want to better understand these issues and have an open mind, then read a book. Those who you would be arguing against will not have as good an understanding of political theory as books written by the experts. It won't give you the pleasure of having "beaten someone in the free market of ideas", but it's the best way for you to actually understand the underlying philosophies that compose different political ideologies. Ask me if you'd like any recommendations for getting into Leftist thought 🙂.

In general, become skeptical of political discourse you see in the media, mainstream or social or otherwise. Keep in mind these are people trying to "win" and change minds, and are likely not delving into underlying theory. Clips of gotcha moments or isolated "good points" may feel good to share, but they are unlikely to change minds.

Improving others' understanding

If you want to convince others to shift their political stance, then recommending books for them to read is also probably your best bet. You can assist someone on their political journey, but you can't force them onto it. If you fancy yourself skilled at distilling information and already have a very good understanding of not just the position you're arguing but the underlying theory, then by all means you can write your own "explainers" on the topic and distribute those as well. May I propose a Digital Garden?

Being productive

Rather than having political discourse for its own sake, apply the topic to something that can be acted upon, such as changing a rule within the community (might I suggest discussing a replacement or set of replacement rules to get rid of an existing "No Politics" Rule 😉). These are much more likely to work constructively towards finding consensus, and can actually lead to productive changes that affect the participants. You'll see issues raised and be able to find ways to solve them amicably rather than trying to dismiss them. Naturally this only applies in certain contexts and discussing current events won't often be translatable to the community directly.

Also, don't neglect your physical community. All of this article has been centering on online conversations, but if your goal is to be productive and make meaningful change, then go out and do something! Join a local org - I recommend checking out Mutual Aid Hub, but a local political org can also help with mobilizing for protests and other events, which supports the cause far more than arguing with strangers on the internet. The specific org doesn't matter too much - one's political journey will likely involve multiple orgs - but meeting up with comrades offline at all will provide useful and fulfilling experiences. There's a list of leftist organizations here to help you in your search; it has a lot of other useful resources as well.

',25),y=JSON.parse('{"title":"Debate","description":"","frontmatter":{"alias":"Debating","public":"true","slug":"debate","title":"Debate","prev":false,"next":false},"headers":[],"relativePath":"garden/debate/index.md","filePath":"garden/debate/index.md"}'),c={name:"garden/debate/index.md"},v=Object.assign(c,{setup(p){const a=i();return(g,m)=>(l(),n("div",null,[h,e("p",null,[r("986 words, ~5 minute read. "),e("span",{innerHTML:t(o)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),u]))}});export{y as __pageData,v as default}; +import{d as o}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as n,Q as e,K as r,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Debate",-1),d=["innerHTML"],u=s('
Referenced by:"No Politics" Rules

Debate takes many forms, but for this article we're going to group them into three categories, and argue why none of them work towards actually finding the best solution to a problem. These categories are going to be structured debates, public debates, and conversational debates.

Structured debates

These are the formal debates held in academic contexts and tournaments. These have predefined formats like Lincoln-Douglas or Oxford style, and have the explicit goal of one of the individuals being judged as the winner not based on having the correct stance or even making good arguments, but for their performance in the debate, dictated by their charisma and rhetoric and ability to respond quickly.

While specific formats vary, many of these debates are filled with gish galloping and other rhetorical flourishes. Gish galloping is when a debater speeds through many arguments with the goal of overwhelming the adversary, as its easier and faster to make unsubstantiated claims than it is to contest them. This is a common technique not just in structured debates but all debates. If you're ever watched Ben Shapiro debate (and you have my sympathies), you've seen the gish gallop technique in action.

These debates are adversarial by design, and there is no opportunity for constructive discussion aimed at arriving at the correct conclusion. The people participating in these debates certainly prepare greatly for arguing their positions, but additionally learn a great many skills and techniques unique to the formal debate format.

It should likely go without saying, but this is clearly not meant to be how new ideas are formed or how solutions get created. This is an academic exercise completely divorced from actually solving the problems in our society. The debates are not intended to influence people or impact policy. The skills developed here do not translate to collaborative problem-solving environments.

Public debates

Public debates are debates held by public figures, such as the presidential debates or debates involving political pundits like Ben Shapiro or Cenk Uyghur. They don't have judges or formal winners and losers. Similar to structured debates, these are adversarial debates that don't aim to form a consensus by the end of the debate. Instead, the goal here is for each debater to improve public sentiment towards themselves.

Gish galloping and its companion reverse gish galloping, whereby a flaw in one specific point is used to dismiss the entire argument, are commonly used here, alongside ad hominem attacks and other fallacies. Since the goal is to change public perception, appeals to emotion work greatly here.

As before, these are not intended to change the minds of either participant. They may influence the audience to view a participant or their position more favorably, but this isn't some victory for the "free market of ideas" - the influence is still tied more to the participants' charisma and rhetorical skill rather than the correctness of their position. Several on the left have argued against the utility of these debates, debate culture, and "debate bro" influencers, such as Wisecrack and Noah Samsen.

Conversational debates

This refers to impromptu political discourse, and typically happens between non-influencers on social media. Its debate for the rest of us! Since this is inherently informal there's no enforced structure, but typically they're adversarial since the conversation starts by someone taking issue with something someone else said.

As with the other types, being adversarial means closing one's mind and framing the debate as a competition with a winner and a loser rather than a constructive conversation building towards consensus. One's ego gets intertwined with being correct, and conceding points becomes akin to admitting personal failures.

Being conversational, participants can come and go and anyone can try initiating arguments. This gives rise to sealioning, a form of bad faith debater that exhausts others with their continuous requests for citations or other responses under the pretense of civility. While they can be grating on anyone, their especially a problem for influencers or those who "go viral". The issue is the sheer amount of criticism, the mental and emotional drain filtering through it can be, and the nebulousness of what even is "valid criticism". Innuendo Studios discussed this concept in Why Don't You Respond to Criticism?.

Alternatives to debate

Improving your understanding

If you want to better understand these issues and have an open mind, then read a book. Those who you would be arguing against will not have as good an understanding of political theory as books written by the experts. It won't give you the pleasure of having "beaten someone in the free market of ideas", but it's the best way for you to actually understand the underlying philosophies that compose different political ideologies. Ask me if you'd like any recommendations for getting into Leftist thought 🙂.

In general, become skeptical of political discourse you see in the media, mainstream or social or otherwise. Keep in mind these are people trying to "win" and change minds, and are likely not delving into underlying theory. Clips of gotcha moments or isolated "good points" may feel good to share, but they are unlikely to change minds.

Improving others' understanding

If you want to convince others to shift their political stance, then recommending books for them to read is also probably your best bet. You can assist someone on their political journey, but you can't force them onto it. If you fancy yourself skilled at distilling information and already have a very good understanding of not just the position you're arguing but the underlying theory, then by all means you can write your own "explainers" on the topic and distribute those as well. May I propose a Digital Garden?

Being productive

Rather than having political discourse for its own sake, apply the topic to something that can be acted upon, such as changing a rule within the community (might I suggest discussing a replacement or set of replacement rules to get rid of an existing "No Politics" Rule 😉). These are much more likely to work constructively towards finding consensus, and can actually lead to productive changes that affect the participants. You'll see issues raised and be able to find ways to solve them amicably rather than trying to dismiss them. Naturally this only applies in certain contexts and discussing current events won't often be translatable to the community directly.

Also, don't neglect your physical community. All of this article has been centering on online conversations, but if your goal is to be productive and make meaningful change, then go out and do something! Join a local org - I recommend checking out Mutual Aid Hub, but a local political org can also help with mobilizing for protests and other events, which supports the cause far more than arguing with strangers on the internet. The specific org doesn't matter too much - one's political journey will likely involve multiple orgs - but meeting up with comrades offline at all will provide useful and fulfilling experiences. There's a list of leftist organizations here to help you in your search; it has a lot of other useful resources as well.

',25),y=JSON.parse('{"title":"Debate","description":"","frontmatter":{"alias":"Debating","public":"true","slug":"debate","title":"Debate","prev":false,"next":false},"headers":[],"relativePath":"garden/debate/index.md","filePath":"garden/debate/index.md"}'),c={name:"garden/debate/index.md"},v=Object.assign(c,{setup(p){const a=i();return(g,m)=>(l(),n("div",null,[h,e("p",null,[r("986 words, ~5 minute read. "),e("span",{innerHTML:t(o)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),u]))}});export{y as __pageData,v as default}; diff --git a/assets/garden_debate_index.md.DcD9KhbD.lean.js b/assets/garden_debate_index.md.KJcHmWUU.lean.js similarity index 91% rename from assets/garden_debate_index.md.DcD9KhbD.lean.js rename to assets/garden_debate_index.md.KJcHmWUU.lean.js index 87bf5de6f..2958b6040 100644 --- a/assets/garden_debate_index.md.DcD9KhbD.lean.js +++ b/assets/garden_debate_index.md.KJcHmWUU.lean.js @@ -1 +1 @@ -import{d as o}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as n,Q as e,K as r,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Debate",-1),d=["innerHTML"],u=s("",25),y=JSON.parse('{"title":"Debate","description":"","frontmatter":{"alias":"Debating","public":"true","slug":"debate","title":"Debate","prev":false,"next":false},"headers":[],"relativePath":"garden/debate/index.md","filePath":"garden/debate/index.md"}'),c={name:"garden/debate/index.md"},v=Object.assign(c,{setup(p){const a=i();return(g,m)=>(l(),n("div",null,[h,e("p",null,[r("986 words, ~5 minute read. "),e("span",{innerHTML:t(o)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),u]))}});export{y as __pageData,v as default}; +import{d as o}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as n,Q as e,K as r,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Debate",-1),d=["innerHTML"],u=s("",25),y=JSON.parse('{"title":"Debate","description":"","frontmatter":{"alias":"Debating","public":"true","slug":"debate","title":"Debate","prev":false,"next":false},"headers":[],"relativePath":"garden/debate/index.md","filePath":"garden/debate/index.md"}'),c={name:"garden/debate/index.md"},v=Object.assign(c,{setup(p){const a=i();return(g,m)=>(l(),n("div",null,[h,e("p",null,[r("986 words, ~5 minute read. "),e("span",{innerHTML:t(o)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),u]))}});export{y as __pageData,v as default}; diff --git a/assets/garden_decentralized-identity_index.md.y4RFh3rh.js b/assets/garden_decentralized-identity_index.md.BEIMlpi0.js similarity index 98% rename from assets/garden_decentralized-identity_index.md.y4RFh3rh.js rename to assets/garden_decentralized-identity_index.md.BEIMlpi0.js index 84bc7262c..2c8bf0614 100644 --- a/assets/garden_decentralized-identity_index.md.y4RFh3rh.js +++ b/assets/garden_decentralized-identity_index.md.BEIMlpi0.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as r,q as n,Q as e,K as o,u as t,ag as s,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Decentralized Identity",-1),h=["innerHTML"],c=s('
Referenced by:CommuneDecentralized Social MediaFedi v2Incremental SocialNostrWeird
Tags:Decentralized

Decentralized identity is when someone's identity can be authenticated without the reliance of a central authoritative source. Keypairs are the most common form of this, where someone generates a pair of keys - one private and one public, with which they can sign a message in a way that allows others to verify it came from someone with access to the private key and was not tampered with. IndieAuth is another version of decentralized identity, used by parts of The IndieWeb.

User Experience

Clients can silently generate key pairs, and allow methods for migration or "linking" identities. The client could also include backup methods like saving the private key to Google drive or similar services. The point here would to have convenient default choices that are reasonably secure, while allowing people to have full agency to choose their own storage and backup solutions.

Sharing your profile with others may be tricky. If you're registered on a nameserver then you can just share your handle there, similar to fediverse profile handles. Otherwise, I think QR codes are the most user friendly solution. A client could register a URI handler that takes a public key and optionally a relay server that has the information about that identity. Adding the identity to your friends list could happen fully offline, although pulling the profile information would require a connection. Perhaps that, too, could be encoded in a (likely separate) QR code.

Profile Information

For casual conversation, a nickname in the profile data should be sufficient. Once a client interacts with someone, they can be added as a contact as a way of verifying the next conversation with someone with that username is actually the same person as before.

For situations where you want to verify an identity actually has a credentials they claim, you can query a nameserver that vouches for them. For example, whitehouse.gov would have a nameserver that specifies which identity is the actual president of the United States (and other government officials).

There could be nameservers that allow you to openly "register" your identity with them to get a unique human readable username you can include on billboards or other visual media where you want someone to be able to memorize the identifier, rather than scan a QR code or something.

For more details on how these decentralized usernames would work, check out Petnames.

Identity Recovery

If you lose access to your account, it's gone forever. That is why I think there should be defaults to backup your private key to existing reliable servers, even if they're owned by large corporations. Otherwise I would see someone have their phone stolen, lost, or upgraded and be surprised when their account is now inaccessible.

If you do lose your account and create a new identity, you could have others "vouch" for the new identity being an alias for the previous identity. You could verify your new identity with people IRL, and then other clients can see those vouches publicly and, after sufficient quantity, just implicitly assume they're the same (although with some sort of indicator, so if this gets abused, users are at least aware of the possibility of impersonation.

',15),w=JSON.parse('{"title":"Decentralized Identity","description":"","frontmatter":{"alias":"Federated Identity","public":"true","slug":"decentralized-identity","tags":["Decentralized"],"title":"Decentralized Identity","prev":false,"next":false},"headers":[],"relativePath":"garden/decentralized-identity/index.md","filePath":"garden/decentralized-identity/index.md"}'),u={name:"garden/decentralized-identity/index.md"},v=Object.assign(u,{setup(m){const a=r();return(p,y)=>(d(),n("div",null,[l,e("p",null,[o("532 words, ~3 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,h)]),c]))}});export{w as __pageData,v as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as r,q as n,Q as e,K as o,u as t,ag as s,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Decentralized Identity",-1),h=["innerHTML"],c=s('
Referenced by:CommuneDecentralized Social MediaFedi v2Incremental SocialNostrWeird
Tags:Decentralized

Decentralized identity is when someone's identity can be authenticated without the reliance of a central authoritative source. Keypairs are the most common form of this, where someone generates a pair of keys - one private and one public, with which they can sign a message in a way that allows others to verify it came from someone with access to the private key and was not tampered with. IndieAuth is another version of decentralized identity, used by parts of The IndieWeb.

User Experience

Clients can silently generate key pairs, and allow methods for migration or "linking" identities. The client could also include backup methods like saving the private key to Google drive or similar services. The point here would to have convenient default choices that are reasonably secure, while allowing people to have full agency to choose their own storage and backup solutions.

Sharing your profile with others may be tricky. If you're registered on a nameserver then you can just share your handle there, similar to fediverse profile handles. Otherwise, I think QR codes are the most user friendly solution. A client could register a URI handler that takes a public key and optionally a relay server that has the information about that identity. Adding the identity to your friends list could happen fully offline, although pulling the profile information would require a connection. Perhaps that, too, could be encoded in a (likely separate) QR code.

Profile Information

For casual conversation, a nickname in the profile data should be sufficient. Once a client interacts with someone, they can be added as a contact as a way of verifying the next conversation with someone with that username is actually the same person as before.

For situations where you want to verify an identity actually has a credentials they claim, you can query a nameserver that vouches for them. For example, whitehouse.gov would have a nameserver that specifies which identity is the actual president of the United States (and other government officials).

There could be nameservers that allow you to openly "register" your identity with them to get a unique human readable username you can include on billboards or other visual media where you want someone to be able to memorize the identifier, rather than scan a QR code or something.

For more details on how these decentralized usernames would work, check out Petnames.

Identity Recovery

If you lose access to your account, it's gone forever. That is why I think there should be defaults to backup your private key to existing reliable servers, even if they're owned by large corporations. Otherwise I would see someone have their phone stolen, lost, or upgraded and be surprised when their account is now inaccessible.

If you do lose your account and create a new identity, you could have others "vouch" for the new identity being an alias for the previous identity. You could verify your new identity with people IRL, and then other clients can see those vouches publicly and, after sufficient quantity, just implicitly assume they're the same (although with some sort of indicator, so if this gets abused, users are at least aware of the possibility of impersonation.

',15),w=JSON.parse('{"title":"Decentralized Identity","description":"","frontmatter":{"alias":"Federated Identity","public":"true","slug":"decentralized-identity","tags":["Decentralized"],"title":"Decentralized Identity","prev":false,"next":false},"headers":[],"relativePath":"garden/decentralized-identity/index.md","filePath":"garden/decentralized-identity/index.md"}'),u={name:"garden/decentralized-identity/index.md"},v=Object.assign(u,{setup(m){const a=r();return(p,y)=>(d(),n("div",null,[l,e("p",null,[o("532 words, ~3 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,h)]),c]))}});export{w as __pageData,v as default}; diff --git a/assets/garden_decentralized-identity_index.md.y4RFh3rh.lean.js b/assets/garden_decentralized-identity_index.md.BEIMlpi0.lean.js similarity index 92% rename from assets/garden_decentralized-identity_index.md.y4RFh3rh.lean.js rename to assets/garden_decentralized-identity_index.md.BEIMlpi0.lean.js index 2129ad371..32cd651d4 100644 --- a/assets/garden_decentralized-identity_index.md.y4RFh3rh.lean.js +++ b/assets/garden_decentralized-identity_index.md.BEIMlpi0.lean.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as r,q as n,Q as e,K as o,u as t,ag as s,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Decentralized Identity",-1),h=["innerHTML"],c=s("",15),w=JSON.parse('{"title":"Decentralized Identity","description":"","frontmatter":{"alias":"Federated Identity","public":"true","slug":"decentralized-identity","tags":["Decentralized"],"title":"Decentralized Identity","prev":false,"next":false},"headers":[],"relativePath":"garden/decentralized-identity/index.md","filePath":"garden/decentralized-identity/index.md"}'),u={name:"garden/decentralized-identity/index.md"},v=Object.assign(u,{setup(m){const a=r();return(p,y)=>(d(),n("div",null,[l,e("p",null,[o("532 words, ~3 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,h)]),c]))}});export{w as __pageData,v as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as r,q as n,Q as e,K as o,u as t,ag as s,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Decentralized Identity",-1),h=["innerHTML"],c=s("",15),w=JSON.parse('{"title":"Decentralized Identity","description":"","frontmatter":{"alias":"Federated Identity","public":"true","slug":"decentralized-identity","tags":["Decentralized"],"title":"Decentralized Identity","prev":false,"next":false},"headers":[],"relativePath":"garden/decentralized-identity/index.md","filePath":"garden/decentralized-identity/index.md"}'),u={name:"garden/decentralized-identity/index.md"},v=Object.assign(u,{setup(m){const a=r();return(p,y)=>(d(),n("div",null,[l,e("p",null,[o("532 words, ~3 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,h)]),c]))}});export{w as __pageData,v as default}; diff --git a/assets/garden_decentralized-moderation_index.md.Vc-f-eOL.js b/assets/garden_decentralized-moderation_index.md.ueaXQznW.js similarity index 99% rename from assets/garden_decentralized-moderation_index.md.Vc-f-eOL.js rename to assets/garden_decentralized-moderation_index.md.ueaXQznW.js index 2a863ee66..62973a9f3 100644 --- a/assets/garden_decentralized-moderation_index.md.Vc-f-eOL.js +++ b/assets/garden_decentralized-moderation_index.md.ueaXQznW.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as n,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Decentralized Moderation",-1),c=["innerHTML"],h=s('
Referenced by:"No Politics" RulesDecentralized Social MediaDigital LocalityFedi v2ModerationVirality
Tags:Decentralized

Naturally, this refers to how to properly Moderate content, typically within Social Media, in a Decentralized fashion - no central authority defining or enforcing the rules. This typically involves organizing under Anarchist principles.

Of course, the standard tools individuals are already familiar for self-moderating their content will still apply - muting or blocking people. This is not sufficient though, as it still means people would need to be exposed to the bad content before being able to block it, and it does nothing to combat the spread of misinformation.

For specifically tackling the problem of keeping fascism out of a community, I recommend this video (and the whole series) by Innuendo Studios.

Approaches

Labelers

ATProto designed a system of labelers that anyone can create and follow. Labeling services mark accounts or posts as NSFW, gore, etc. These will cause the post to either be hidden entirely or obscured until the user clicks through a warning. These labelers can be configured by the app designer or the user themselves. The labelers can be linked to reporting services or setup to label based on arbitrary criteria, such as sending each reported post to an LLM for judgement.

I have several concerns with this system. Firstly, these labelers are likely to accumulate influence as the popular ones get used more and thus become more popular. This centralizes power.

The second concern is with malicious labelers. If a labeler decides to create a list of people known to be a member of a specific marginalized community, there's little to no action anyone can do to stop it.

Lastly, this is moderation through the use of blocklists. This isn't inherently bad, but it's a double edged sword, as I discuss here).

Network of vouches

Identities could have a system by which they vouch for or against other identities that they are human and make content worth looking at, and clients could use this network of vouches to filter posts to display or retrieve. For example, a user may say they only want to see posts made by identities within a chain of 4 vouches to themselves. Upon account creation, users could be prompted to vouch for IRL friends or some popular figures within topics they care about to get started. In theory the longer the chain can be, the more varied the content a user will see, and the more likely for it to be something they disagree with. This would allow users to customize how narrow their feed is at a given time by just changing the max chain length. They can also continue vouching for more people to more precisely expand their feed.

Clients could include tools to analyze their network of vouches, such as displaying all the identities within certain max lengths, or viewing what chain was followed for a specific post to have been displayed. Clients could also add additional tools to customize the chain, like being able to ignore a specific user's vouches or reposts/reblogs. They could also treat any interaction as a vouch, overriding the max chain length for different contexts, such as when used for counting likes.

Specific entity types, such as one representing a reddit-like community, could display all replies rather than use the network of trust, and offer controls like only counting likes from within the network when sorting the replies.

This would essentially be an alternative to how current fediverse applications block entire instances as a heuristic, so they can get rid of undesirable content while minimizing how much of it they need to see before doing so. Except in this model, you can always reach people regardless of what server they decided to use, and the controls of in the hands of the individual.

Digital Locality

Similar to the network of vouches, a network with digital locality naturally limits the amount of content you'll see, essentially eliminating bots and spam as well as organically filtering the content you see based on the people you interact with.

',19),b=JSON.parse('{"title":"Decentralized Moderation","description":"","frontmatter":{"public":"tags:: Decentralized","slug":"decentralized-moderation","title":"Decentralized Moderation","prev":false,"next":false},"headers":[],"relativePath":"garden/decentralized-moderation/index.md","filePath":"garden/decentralized-moderation/index.md"}'),u={name:"garden/decentralized-moderation/index.md"},w=Object.assign(u,{setup(p){const t=o();return(m,f)=>(l(),n("div",null,[d,e("p",null,[r("661 words, ~4 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),h]))}});export{b as __pageData,w as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as n,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Decentralized Moderation",-1),c=["innerHTML"],h=s('
Referenced by:"No Politics" RulesDecentralized Social MediaDigital LocalityFedi v2ModerationVirality
Tags:Decentralized

Naturally, this refers to how to properly Moderate content, typically within Social Media, in a Decentralized fashion - no central authority defining or enforcing the rules. This typically involves organizing under Anarchist principles.

Of course, the standard tools individuals are already familiar for self-moderating their content will still apply - muting or blocking people. This is not sufficient though, as it still means people would need to be exposed to the bad content before being able to block it, and it does nothing to combat the spread of misinformation.

For specifically tackling the problem of keeping fascism out of a community, I recommend this video (and the whole series) by Innuendo Studios.

Approaches

Labelers

ATProto designed a system of labelers that anyone can create and follow. Labeling services mark accounts or posts as NSFW, gore, etc. These will cause the post to either be hidden entirely or obscured until the user clicks through a warning. These labelers can be configured by the app designer or the user themselves. The labelers can be linked to reporting services or setup to label based on arbitrary criteria, such as sending each reported post to an LLM for judgement.

I have several concerns with this system. Firstly, these labelers are likely to accumulate influence as the popular ones get used more and thus become more popular. This centralizes power.

The second concern is with malicious labelers. If a labeler decides to create a list of people known to be a member of a specific marginalized community, there's little to no action anyone can do to stop it.

Lastly, this is moderation through the use of blocklists. This isn't inherently bad, but it's a double edged sword, as I discuss here).

Network of vouches

Identities could have a system by which they vouch for or against other identities that they are human and make content worth looking at, and clients could use this network of vouches to filter posts to display or retrieve. For example, a user may say they only want to see posts made by identities within a chain of 4 vouches to themselves. Upon account creation, users could be prompted to vouch for IRL friends or some popular figures within topics they care about to get started. In theory the longer the chain can be, the more varied the content a user will see, and the more likely for it to be something they disagree with. This would allow users to customize how narrow their feed is at a given time by just changing the max chain length. They can also continue vouching for more people to more precisely expand their feed.

Clients could include tools to analyze their network of vouches, such as displaying all the identities within certain max lengths, or viewing what chain was followed for a specific post to have been displayed. Clients could also add additional tools to customize the chain, like being able to ignore a specific user's vouches or reposts/reblogs. They could also treat any interaction as a vouch, overriding the max chain length for different contexts, such as when used for counting likes.

Specific entity types, such as one representing a reddit-like community, could display all replies rather than use the network of trust, and offer controls like only counting likes from within the network when sorting the replies.

This would essentially be an alternative to how current fediverse applications block entire instances as a heuristic, so they can get rid of undesirable content while minimizing how much of it they need to see before doing so. Except in this model, you can always reach people regardless of what server they decided to use, and the controls of in the hands of the individual.

Digital Locality

Similar to the network of vouches, a network with digital locality naturally limits the amount of content you'll see, essentially eliminating bots and spam as well as organically filtering the content you see based on the people you interact with.

',19),b=JSON.parse('{"title":"Decentralized Moderation","description":"","frontmatter":{"public":"tags:: Decentralized","slug":"decentralized-moderation","title":"Decentralized Moderation","prev":false,"next":false},"headers":[],"relativePath":"garden/decentralized-moderation/index.md","filePath":"garden/decentralized-moderation/index.md"}'),u={name:"garden/decentralized-moderation/index.md"},w=Object.assign(u,{setup(p){const t=o();return(m,f)=>(l(),n("div",null,[d,e("p",null,[r("661 words, ~4 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),h]))}});export{b as __pageData,w as default}; diff --git a/assets/garden_decentralized-moderation_index.md.Vc-f-eOL.lean.js b/assets/garden_decentralized-moderation_index.md.ueaXQznW.lean.js similarity index 92% rename from assets/garden_decentralized-moderation_index.md.Vc-f-eOL.lean.js rename to assets/garden_decentralized-moderation_index.md.ueaXQznW.lean.js index 8efd3a7f6..05d3cae48 100644 --- a/assets/garden_decentralized-moderation_index.md.Vc-f-eOL.lean.js +++ b/assets/garden_decentralized-moderation_index.md.ueaXQznW.lean.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as n,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Decentralized Moderation",-1),c=["innerHTML"],h=s("",19),b=JSON.parse('{"title":"Decentralized Moderation","description":"","frontmatter":{"public":"tags:: Decentralized","slug":"decentralized-moderation","title":"Decentralized Moderation","prev":false,"next":false},"headers":[],"relativePath":"garden/decentralized-moderation/index.md","filePath":"garden/decentralized-moderation/index.md"}'),u={name:"garden/decentralized-moderation/index.md"},w=Object.assign(u,{setup(p){const t=o();return(m,f)=>(l(),n("div",null,[d,e("p",null,[r("661 words, ~4 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),h]))}});export{b as __pageData,w as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as n,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Decentralized Moderation",-1),c=["innerHTML"],h=s("",19),b=JSON.parse('{"title":"Decentralized Moderation","description":"","frontmatter":{"public":"tags:: Decentralized","slug":"decentralized-moderation","title":"Decentralized Moderation","prev":false,"next":false},"headers":[],"relativePath":"garden/decentralized-moderation/index.md","filePath":"garden/decentralized-moderation/index.md"}'),u={name:"garden/decentralized-moderation/index.md"},w=Object.assign(u,{setup(p){const t=o();return(m,f)=>(l(),n("div",null,[d,e("p",null,[r("661 words, ~4 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),h]))}});export{b as __pageData,w as default}; diff --git a/assets/garden_decentralized-social-media_index.md.D0uxpYG3.js b/assets/garden_decentralized-social-media_index.md.B0rgV0sO.js similarity index 96% rename from assets/garden_decentralized-social-media_index.md.D0uxpYG3.js rename to assets/garden_decentralized-social-media_index.md.B0rgV0sO.js index a4d608e68..792dcc2c0 100644 --- a/assets/garden_decentralized-social-media_index.md.D0uxpYG3.js +++ b/assets/garden_decentralized-social-media_index.md.B0rgV0sO.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as r,q as i,Q as e,K as n,u as a,ag as l,p as s}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Decentralized Social Media",-1),c=["innerHTML"],m=l('
Referenced by:ModerationNostrVirality

Social Media that is fully Decentralized (and not just Federated Social Media ). Such a network would require Decentralized Moderation and Decentralized Identity. The Agentic Fediverse strives to be a decentralized social media.

Nostr is the largest currently existing example of a fully decentralized social media.

',4),z=JSON.parse('{"title":"Decentralized Social Media","description":"","frontmatter":{"public":"true","slug":"decentralized-social-media","title":"Decentralized Social Media","prev":false,"next":false},"headers":[],"relativePath":"garden/decentralized-social-media/index.md","filePath":"garden/decentralized-social-media/index.md"}'),_={name:"garden/decentralized-social-media/index.md"},x=Object.assign(_,{setup(f){const d=r();return(u,h)=>(s(),i("div",null,[o,e("p",null,[n("25 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(d).page.value.relativePath}`]},null,8,c)]),m]))}});export{z as __pageData,x as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as r,q as i,Q as e,K as n,u as a,ag as l,p as s}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Decentralized Social Media",-1),c=["innerHTML"],m=l('
Referenced by:ModerationNostrVirality

Social Media that is fully Decentralized (and not just Federated Social Media ). Such a network would require Decentralized Moderation and Decentralized Identity. The Agentic Fediverse strives to be a decentralized social media.

Nostr is the largest currently existing example of a fully decentralized social media.

',4),z=JSON.parse('{"title":"Decentralized Social Media","description":"","frontmatter":{"public":"true","slug":"decentralized-social-media","title":"Decentralized Social Media","prev":false,"next":false},"headers":[],"relativePath":"garden/decentralized-social-media/index.md","filePath":"garden/decentralized-social-media/index.md"}'),_={name:"garden/decentralized-social-media/index.md"},x=Object.assign(_,{setup(f){const d=r();return(u,h)=>(s(),i("div",null,[o,e("p",null,[n("25 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(d).page.value.relativePath}`]},null,8,c)]),m]))}});export{z as __pageData,x as default}; diff --git a/assets/garden_decentralized-social-media_index.md.D0uxpYG3.lean.js b/assets/garden_decentralized-social-media_index.md.B0rgV0sO.lean.js similarity index 92% rename from assets/garden_decentralized-social-media_index.md.D0uxpYG3.lean.js rename to assets/garden_decentralized-social-media_index.md.B0rgV0sO.lean.js index 5521ff9b4..2dffa71ef 100644 --- a/assets/garden_decentralized-social-media_index.md.D0uxpYG3.lean.js +++ b/assets/garden_decentralized-social-media_index.md.B0rgV0sO.lean.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as r,q as i,Q as e,K as n,u as a,ag as l,p as s}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Decentralized Social Media",-1),c=["innerHTML"],m=l("",4),z=JSON.parse('{"title":"Decentralized Social Media","description":"","frontmatter":{"public":"true","slug":"decentralized-social-media","title":"Decentralized Social Media","prev":false,"next":false},"headers":[],"relativePath":"garden/decentralized-social-media/index.md","filePath":"garden/decentralized-social-media/index.md"}'),_={name:"garden/decentralized-social-media/index.md"},x=Object.assign(_,{setup(f){const d=r();return(u,h)=>(s(),i("div",null,[o,e("p",null,[n("25 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(d).page.value.relativePath}`]},null,8,c)]),m]))}});export{z as __pageData,x as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as r,q as i,Q as e,K as n,u as a,ag as l,p as s}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Decentralized Social Media",-1),c=["innerHTML"],m=l("",4),z=JSON.parse('{"title":"Decentralized Social Media","description":"","frontmatter":{"public":"true","slug":"decentralized-social-media","title":"Decentralized Social Media","prev":false,"next":false},"headers":[],"relativePath":"garden/decentralized-social-media/index.md","filePath":"garden/decentralized-social-media/index.md"}'),_={name:"garden/decentralized-social-media/index.md"},x=Object.assign(_,{setup(f){const d=r();return(u,h)=>(s(),i("div",null,[o,e("p",null,[n("25 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(d).page.value.relativePath}`]},null,8,c)]),m]))}});export{z as __pageData,x as default}; diff --git a/assets/garden_decentralized_index.md.B4L35X0Y.js b/assets/garden_decentralized_index.md.bryhD8xj.js similarity index 97% rename from assets/garden_decentralized_index.md.B4L35X0Y.js rename to assets/garden_decentralized_index.md.bryhD8xj.js index 598a4980f..fc12a9a92 100644 --- a/assets/garden_decentralized_index.md.B4L35X0Y.js +++ b/assets/garden_decentralized_index.md.bryhD8xj.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as n,Q as e,K as d,u as a,ag as s,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Decentralized",-1),c=["innerHTML"],h=s('
Referenced by:CommuneDecentralized ModerationDecentralized Social MediaDigital LocalityFedi v2MatrixSocial MediaVirality
Tagged by:Decentralized IdentityDecentralized ModerationNostr

Decentralized networks are networks with no central source of authority, all the way to the individual level. This provides many useful advantages to the user, such as data ownership, privacy, and increased agency over the rules you must follow and the client you use. This also means democratizing the service and helping protect it from Enshittification. There's not many examples of fully decentralized networks today, but some common examples are RSS, cryptocurrency, torrenting, and other peer-to-peer software. Some energy grids are decentralized, relying on individuals generating their own power and sharing surplus with neighbors.

An important caveat to the use of the term decentralization is that federated networks are often (erroneously) considered decentralized. Federated networks are ones where users have to join or create an entity, which is usually non-trivial, and will then be subject to the rules and limitations of that entity, but can theoretically then communicate with users who are members of other entities. Common examples are email and the Fediverse. The distinction is important because federations trend towards a handful of large entities, thus centralizing power still. This happens due to the difficulty in migrating between servers, creating a new server, and even just picking a specific server to join. There is work being done in creating a properly decentralized alternative to the fediverse called the Agentic Fediverse.

',5),_=JSON.parse('{"title":"Decentralized","description":"","frontmatter":{"alias":"Federated","public":"true","slug":"decentralized","title":"Decentralized","prev":false,"next":false},"headers":[],"relativePath":"garden/decentralized/index.md","filePath":"garden/decentralized/index.md"}'),m={name:"garden/decentralized/index.md"},v=Object.assign(m,{setup(u){const t=i();return(f,g)=>(o(),n("div",null,[l,e("p",null,[d("225 words, ~1 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),h]))}});export{_ as __pageData,v as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as n,Q as e,K as d,u as a,ag as s,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Decentralized",-1),c=["innerHTML"],h=s('
Referenced by:CommuneDecentralized ModerationDecentralized Social MediaDigital LocalityFedi v2MatrixSocial MediaVirality
Tagged by:Decentralized IdentityDecentralized ModerationNostr

Decentralized networks are networks with no central source of authority, all the way to the individual level. This provides many useful advantages to the user, such as data ownership, privacy, and increased agency over the rules you must follow and the client you use. This also means democratizing the service and helping protect it from Enshittification. There's not many examples of fully decentralized networks today, but some common examples are RSS, cryptocurrency, torrenting, and other peer-to-peer software. Some energy grids are decentralized, relying on individuals generating their own power and sharing surplus with neighbors.

An important caveat to the use of the term decentralization is that federated networks are often (erroneously) considered decentralized. Federated networks are ones where users have to join or create an entity, which is usually non-trivial, and will then be subject to the rules and limitations of that entity, but can theoretically then communicate with users who are members of other entities. Common examples are email and the Fediverse. The distinction is important because federations trend towards a handful of large entities, thus centralizing power still. This happens due to the difficulty in migrating between servers, creating a new server, and even just picking a specific server to join. There is work being done in creating a properly decentralized alternative to the fediverse called the Agentic Fediverse.

',5),_=JSON.parse('{"title":"Decentralized","description":"","frontmatter":{"alias":"Federated","public":"true","slug":"decentralized","title":"Decentralized","prev":false,"next":false},"headers":[],"relativePath":"garden/decentralized/index.md","filePath":"garden/decentralized/index.md"}'),m={name:"garden/decentralized/index.md"},v=Object.assign(m,{setup(u){const t=i();return(f,g)=>(o(),n("div",null,[l,e("p",null,[d("225 words, ~1 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),h]))}});export{_ as __pageData,v as default}; diff --git a/assets/garden_decentralized_index.md.B4L35X0Y.lean.js b/assets/garden_decentralized_index.md.bryhD8xj.lean.js similarity index 91% rename from assets/garden_decentralized_index.md.B4L35X0Y.lean.js rename to assets/garden_decentralized_index.md.bryhD8xj.lean.js index 989f190db..06ff687f4 100644 --- a/assets/garden_decentralized_index.md.B4L35X0Y.lean.js +++ b/assets/garden_decentralized_index.md.bryhD8xj.lean.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as n,Q as e,K as d,u as a,ag as s,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Decentralized",-1),c=["innerHTML"],h=s("",5),_=JSON.parse('{"title":"Decentralized","description":"","frontmatter":{"alias":"Federated","public":"true","slug":"decentralized","title":"Decentralized","prev":false,"next":false},"headers":[],"relativePath":"garden/decentralized/index.md","filePath":"garden/decentralized/index.md"}'),m={name:"garden/decentralized/index.md"},v=Object.assign(m,{setup(u){const t=i();return(f,g)=>(o(),n("div",null,[l,e("p",null,[d("225 words, ~1 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),h]))}});export{_ as __pageData,v as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as n,Q as e,K as d,u as a,ag as s,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Decentralized",-1),c=["innerHTML"],h=s("",5),_=JSON.parse('{"title":"Decentralized","description":"","frontmatter":{"alias":"Federated","public":"true","slug":"decentralized","title":"Decentralized","prev":false,"next":false},"headers":[],"relativePath":"garden/decentralized/index.md","filePath":"garden/decentralized/index.md"}'),m={name:"garden/decentralized/index.md"},v=Object.assign(m,{setup(u){const t=i();return(f,g)=>(o(),n("div",null,[l,e("p",null,[d("225 words, ~1 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),h]))}});export{_ as __pageData,v as default}; diff --git a/assets/garden_dice-armor_index.md.ByqRXWDk.js b/assets/garden_dice-armor_index.md.BvcL1Xmx.js similarity index 99% rename from assets/garden_dice-armor_index.md.ByqRXWDk.js rename to assets/garden_dice-armor_index.md.BvcL1Xmx.js index bd704ab3a..2d21b2d59 100644 --- a/assets/garden_dice-armor_index.md.ByqRXWDk.js +++ b/assets/garden_dice-armor_index.md.BvcL1Xmx.js @@ -1 +1 @@ -import{M as i,q as s,Q as e,K as o,u as t,ag as n,p as r,ai as l,aj as d,ak as h,al as c,am as m,an as p,ao as u,ap as g,aq as f}from"./chunks/framework.Sr2_9k8k.js";import{d as y}from"./chunks/git.data.D-Ga3RhB.js";const b=e("h1",{class:"p-name"},"Dice Armor",-1),v=["innerHTML"],w=n('
Referenced by:Babble Buds
Tags:My Projects

Download it here

Dice Armor is a game that started development as a semester-long project by a team of nine: a producer, a creative director, a narrative writer, an artist, two programmers, and 3 game designers. The information here is about my contributions as the lead programmer over the semester because I can show off stuff like the editor scripts I wrote. I was doing everything from interface coding, editor scripts, integrating Babble Buds, and of course, everything related to the gameplay itself. To date I'm still the lead programmer for the game; for more up-to-date information on the current state of the game please visit the official site.

The build available here was created for showing off at the end of the semester, and as such has some buttons present to make the game easier to skip parts of the game to see all the content: You start with all the dice in the game already in the shop, there's a button to give yourself free money to buy these dice with, and in the duel, there are buttons to force a win or a loss, which can be used to skip the tutorial (not recommended for first-time players).

Dice Armor is a dice dueling game. Players can use abilities, flip dice, and attack each other to win in a dice game that puts chance into the hands of the players. This is what the dueling scene looks like, with a tutorial cutscene happening on top to guide the player through the basics. Also, all the dice are constructed dynamically, using quaternion math to figure out the placement of each component relative to the face it is going on. The die in the middle has one of the player' and opponents' portraits on each of its sides.

For many of the objects I've created, I've made scriptable objects so that game designers can add and modify them easily. Additionally, I would create custom inspectors for the objects to help make them as easy to understand and edit as possible. The opponent's artificial intelligence is made up of many strategies, in a prioritized list. When it is the opponents' turn they go through each strategy and check if they can be run, and if so then the opponent performs the strategy and starts back over at the top of the list of strategies. The + sign under the list of strategies opens an organized dropdown of all the various strategies.

In addition to custom inspector code, I've created new tools for the editor for our game designers to use. This is a duel simulator that will take two opponents and simulate an arbitrary number of duels between them, and output the results and summarize them for you, much much quicker than manually going through the duels, even with an absurdly high timeScale. This will become incredibly useful in making balance changes and testing new dice against existing sets. This is a screenshot of it in edit mode, but in play mode it removes the "Dueling Managers" field and will use whatever the current duel balance settings are, allowing for the GDs to test freely in play mode without worrying about undoing all their changes afterward.

I created the Babble Buds puppet editor and ported the rendering library I wrote for it to C# so it could be used in Unity. Dice Armor has a full campaign using cutscenes made using the Babble Buds cutscene editor, taking advantage of its support for custom commands and fields to control things like talking, giving the player dice and money, starting duels, and controlling player progression through the story.

When a cutscene ends, its final command is to either start a duel or set the next cutscene in the story. In the latter case, there is an additional field for what to call the next cutscene, and what location it takes place. The cutscene is then added to the player's save file, and when they visit the city locations are greyed out until they have at least one action to do there. Each location has a dynamically populated action wheel with a custom range of acceptable angles.

The dice shop is dynamically populated by a list of dice available to the player, which can be changed during cutscenes, and is checked against the dice owned by the player to generate sold-out indicators. On the left, the player can choose to filter the options down to a single dice effect, which also updates the "Buy All" button to buy only all the dice in the current filter.

The inventory works most the same as the shop, but for equipping dice. It also allows you to drag individual dice or entire sets to the equipped dice glyph. While dragging it will highlight all the slots the new dice will be equipped into.

The dice rolling uses the physics engine and detects once the dice have stopped moving, then determines which side is face up based on which of the normals is closest to straight up. It flags the die as cocked if that smallest angle is above a threshold. The dice sink into the table when not rolling to not interfere with any dice that are rolling.

During certain events like winning the game or having the face of a die broken, the players' portraits will flash an emotion for a second. After winning, a random living die from the winning player is chosen to play their "finisher move", a flashy and dramatic effect to end the game. Shown is the arcane mechana's finisher, "Missile Storm".

After development stopped, the project became Open Source - check it out here

',25),D=JSON.parse('{"title":"Dice Armor","description":"","frontmatter":{"public":"true","slug":"dice-armor","tags":["My Projects"],"title":"Dice Armor","prev":false,"next":false},"headers":[],"relativePath":"garden/dice-armor/index.md","filePath":"garden/dice-armor/index.md"}'),_={name:"garden/dice-armor/index.md"},B=Object.assign(_,{setup(k){const a=i();return(T,I)=>(r(),s("div",null,[b,e("p",null,[o("963 words, ~5 minute read. "),e("span",{innerHTML:t(y)[`site/${t(a).page.value.relativePath}`]},null,8,v)]),w]))}});export{D as __pageData,B as default}; +import{M as i,q as s,Q as e,K as o,u as t,ag as n,p as r,ai as l,aj as d,ak as h,al as c,am as m,an as p,ao as u,ap as g,aq as f}from"./chunks/framework.Sr2_9k8k.js";import{d as y}from"./chunks/git.data.BcrWSzMU.js";const b=e("h1",{class:"p-name"},"Dice Armor",-1),v=["innerHTML"],w=n('
Referenced by:Babble Buds
Tags:My Projects

Download it here

Dice Armor is a game that started development as a semester-long project by a team of nine: a producer, a creative director, a narrative writer, an artist, two programmers, and 3 game designers. The information here is about my contributions as the lead programmer over the semester because I can show off stuff like the editor scripts I wrote. I was doing everything from interface coding, editor scripts, integrating Babble Buds, and of course, everything related to the gameplay itself. To date I'm still the lead programmer for the game; for more up-to-date information on the current state of the game please visit the official site.

The build available here was created for showing off at the end of the semester, and as such has some buttons present to make the game easier to skip parts of the game to see all the content: You start with all the dice in the game already in the shop, there's a button to give yourself free money to buy these dice with, and in the duel, there are buttons to force a win or a loss, which can be used to skip the tutorial (not recommended for first-time players).

Dice Armor is a dice dueling game. Players can use abilities, flip dice, and attack each other to win in a dice game that puts chance into the hands of the players. This is what the dueling scene looks like, with a tutorial cutscene happening on top to guide the player through the basics. Also, all the dice are constructed dynamically, using quaternion math to figure out the placement of each component relative to the face it is going on. The die in the middle has one of the player' and opponents' portraits on each of its sides.

For many of the objects I've created, I've made scriptable objects so that game designers can add and modify them easily. Additionally, I would create custom inspectors for the objects to help make them as easy to understand and edit as possible. The opponent's artificial intelligence is made up of many strategies, in a prioritized list. When it is the opponents' turn they go through each strategy and check if they can be run, and if so then the opponent performs the strategy and starts back over at the top of the list of strategies. The + sign under the list of strategies opens an organized dropdown of all the various strategies.

In addition to custom inspector code, I've created new tools for the editor for our game designers to use. This is a duel simulator that will take two opponents and simulate an arbitrary number of duels between them, and output the results and summarize them for you, much much quicker than manually going through the duels, even with an absurdly high timeScale. This will become incredibly useful in making balance changes and testing new dice against existing sets. This is a screenshot of it in edit mode, but in play mode it removes the "Dueling Managers" field and will use whatever the current duel balance settings are, allowing for the GDs to test freely in play mode without worrying about undoing all their changes afterward.

I created the Babble Buds puppet editor and ported the rendering library I wrote for it to C# so it could be used in Unity. Dice Armor has a full campaign using cutscenes made using the Babble Buds cutscene editor, taking advantage of its support for custom commands and fields to control things like talking, giving the player dice and money, starting duels, and controlling player progression through the story.

When a cutscene ends, its final command is to either start a duel or set the next cutscene in the story. In the latter case, there is an additional field for what to call the next cutscene, and what location it takes place. The cutscene is then added to the player's save file, and when they visit the city locations are greyed out until they have at least one action to do there. Each location has a dynamically populated action wheel with a custom range of acceptable angles.

The dice shop is dynamically populated by a list of dice available to the player, which can be changed during cutscenes, and is checked against the dice owned by the player to generate sold-out indicators. On the left, the player can choose to filter the options down to a single dice effect, which also updates the "Buy All" button to buy only all the dice in the current filter.

The inventory works most the same as the shop, but for equipping dice. It also allows you to drag individual dice or entire sets to the equipped dice glyph. While dragging it will highlight all the slots the new dice will be equipped into.

The dice rolling uses the physics engine and detects once the dice have stopped moving, then determines which side is face up based on which of the normals is closest to straight up. It flags the die as cocked if that smallest angle is above a threshold. The dice sink into the table when not rolling to not interfere with any dice that are rolling.

During certain events like winning the game or having the face of a die broken, the players' portraits will flash an emotion for a second. After winning, a random living die from the winning player is chosen to play their "finisher move", a flashy and dramatic effect to end the game. Shown is the arcane mechana's finisher, "Missile Storm".

After development stopped, the project became Open Source - check it out here

',25),D=JSON.parse('{"title":"Dice Armor","description":"","frontmatter":{"public":"true","slug":"dice-armor","tags":["My Projects"],"title":"Dice Armor","prev":false,"next":false},"headers":[],"relativePath":"garden/dice-armor/index.md","filePath":"garden/dice-armor/index.md"}'),_={name:"garden/dice-armor/index.md"},B=Object.assign(_,{setup(k){const a=i();return(T,I)=>(r(),s("div",null,[b,e("p",null,[o("963 words, ~5 minute read. "),e("span",{innerHTML:t(y)[`site/${t(a).page.value.relativePath}`]},null,8,v)]),w]))}});export{D as __pageData,B as default}; diff --git a/assets/garden_dice-armor_index.md.ByqRXWDk.lean.js b/assets/garden_dice-armor_index.md.BvcL1Xmx.lean.js similarity index 92% rename from assets/garden_dice-armor_index.md.ByqRXWDk.lean.js rename to assets/garden_dice-armor_index.md.BvcL1Xmx.lean.js index b047a59a7..9d275726e 100644 --- a/assets/garden_dice-armor_index.md.ByqRXWDk.lean.js +++ b/assets/garden_dice-armor_index.md.BvcL1Xmx.lean.js @@ -1 +1 @@ -import{M as i,q as s,Q as e,K as o,u as t,ag as n,p as r,ai as l,aj as d,ak as h,al as c,am as m,an as p,ao as u,ap as g,aq as f}from"./chunks/framework.Sr2_9k8k.js";import{d as y}from"./chunks/git.data.D-Ga3RhB.js";const b=e("h1",{class:"p-name"},"Dice Armor",-1),v=["innerHTML"],w=n("",25),D=JSON.parse('{"title":"Dice Armor","description":"","frontmatter":{"public":"true","slug":"dice-armor","tags":["My Projects"],"title":"Dice Armor","prev":false,"next":false},"headers":[],"relativePath":"garden/dice-armor/index.md","filePath":"garden/dice-armor/index.md"}'),_={name:"garden/dice-armor/index.md"},B=Object.assign(_,{setup(k){const a=i();return(T,I)=>(r(),s("div",null,[b,e("p",null,[o("963 words, ~5 minute read. "),e("span",{innerHTML:t(y)[`site/${t(a).page.value.relativePath}`]},null,8,v)]),w]))}});export{D as __pageData,B as default}; +import{M as i,q as s,Q as e,K as o,u as t,ag as n,p as r,ai as l,aj as d,ak as h,al as c,am as m,an as p,ao as u,ap as g,aq as f}from"./chunks/framework.Sr2_9k8k.js";import{d as y}from"./chunks/git.data.BcrWSzMU.js";const b=e("h1",{class:"p-name"},"Dice Armor",-1),v=["innerHTML"],w=n("",25),D=JSON.parse('{"title":"Dice Armor","description":"","frontmatter":{"public":"true","slug":"dice-armor","tags":["My Projects"],"title":"Dice Armor","prev":false,"next":false},"headers":[],"relativePath":"garden/dice-armor/index.md","filePath":"garden/dice-armor/index.md"}'),_={name:"garden/dice-armor/index.md"},B=Object.assign(_,{setup(k){const a=i();return(T,I)=>(r(),s("div",null,[b,e("p",null,[o("963 words, ~5 minute read. "),e("span",{innerHTML:t(y)[`site/${t(a).page.value.relativePath}`]},null,8,v)]),w]))}});export{D as __pageData,B as default}; diff --git a/assets/garden_digital-gardens_index.md.ChR2AWpj.js b/assets/garden_digital-gardens_index.md.CBAUQVhO.js similarity index 97% rename from assets/garden_digital-gardens_index.md.ChR2AWpj.js rename to assets/garden_digital-gardens_index.md.CBAUQVhO.js index 59d1be39f..fa376902b 100644 --- a/assets/garden_digital-gardens_index.md.ChR2AWpj.js +++ b/assets/garden_digital-gardens_index.md.CBAUQVhO.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as d,Q as e,K as i,u as a,ag as l,p as o}from"./chunks/framework.Sr2_9k8k.js";const s=e("h1",{class:"p-name"},"Digital Gardens",-1),g=["innerHTML"],h=l('
Referenced by:ChronologicalCommuneDebateFilter BubblesGarden-RSSNetwork of KnowledgeOrchardThe Cozy WebThe Small WebThis Knowledge Hub

Digital Gardens are Freeform collections of information made by an individual or community

This Knowledge Hub is a digital garden

Collections of digital gardens and resources for creating them:

',7),_=JSON.parse('{"title":"Digital Gardens","description":"","frontmatter":{"alias":"Digital Garden, Second Brain, Personal Knowledge Management, The Zettelkasten Method","public":"true","slug":"digital-gardens","title":"Digital Gardens","prev":false,"next":false},"headers":[],"relativePath":"garden/digital-gardens/index.md","filePath":"garden/digital-gardens/index.md"}'),c={name:"garden/digital-gardens/index.md"},x=Object.assign(c,{setup(m){const r=n();return(f,u)=>(o(),d("div",null,[s,e("p",null,[i("67 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,g)]),h]))}});export{_ as __pageData,x as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as d,Q as e,K as i,u as a,ag as l,p as o}from"./chunks/framework.Sr2_9k8k.js";const s=e("h1",{class:"p-name"},"Digital Gardens",-1),g=["innerHTML"],h=l('
Referenced by:ChronologicalCommuneDebateFilter BubblesGarden-RSSNetwork of KnowledgeOrchardThe Cozy WebThe Small WebThis Knowledge Hub

Digital Gardens are Freeform collections of information made by an individual or community

This Knowledge Hub is a digital garden

Collections of digital gardens and resources for creating them:

',7),_=JSON.parse('{"title":"Digital Gardens","description":"","frontmatter":{"alias":"Digital Garden, Second Brain, Personal Knowledge Management, The Zettelkasten Method","public":"true","slug":"digital-gardens","title":"Digital Gardens","prev":false,"next":false},"headers":[],"relativePath":"garden/digital-gardens/index.md","filePath":"garden/digital-gardens/index.md"}'),c={name:"garden/digital-gardens/index.md"},x=Object.assign(c,{setup(m){const r=n();return(f,u)=>(o(),d("div",null,[s,e("p",null,[i("67 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,g)]),h]))}});export{_ as __pageData,x as default}; diff --git a/assets/garden_digital-gardens_index.md.ChR2AWpj.lean.js b/assets/garden_digital-gardens_index.md.CBAUQVhO.lean.js similarity index 92% rename from assets/garden_digital-gardens_index.md.ChR2AWpj.lean.js rename to assets/garden_digital-gardens_index.md.CBAUQVhO.lean.js index da68bf550..d248d2726 100644 --- a/assets/garden_digital-gardens_index.md.ChR2AWpj.lean.js +++ b/assets/garden_digital-gardens_index.md.CBAUQVhO.lean.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as d,Q as e,K as i,u as a,ag as l,p as o}from"./chunks/framework.Sr2_9k8k.js";const s=e("h1",{class:"p-name"},"Digital Gardens",-1),g=["innerHTML"],h=l("",7),_=JSON.parse('{"title":"Digital Gardens","description":"","frontmatter":{"alias":"Digital Garden, Second Brain, Personal Knowledge Management, The Zettelkasten Method","public":"true","slug":"digital-gardens","title":"Digital Gardens","prev":false,"next":false},"headers":[],"relativePath":"garden/digital-gardens/index.md","filePath":"garden/digital-gardens/index.md"}'),c={name:"garden/digital-gardens/index.md"},x=Object.assign(c,{setup(m){const r=n();return(f,u)=>(o(),d("div",null,[s,e("p",null,[i("67 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,g)]),h]))}});export{_ as __pageData,x as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as d,Q as e,K as i,u as a,ag as l,p as o}from"./chunks/framework.Sr2_9k8k.js";const s=e("h1",{class:"p-name"},"Digital Gardens",-1),g=["innerHTML"],h=l("",7),_=JSON.parse('{"title":"Digital Gardens","description":"","frontmatter":{"alias":"Digital Garden, Second Brain, Personal Knowledge Management, The Zettelkasten Method","public":"true","slug":"digital-gardens","title":"Digital Gardens","prev":false,"next":false},"headers":[],"relativePath":"garden/digital-gardens/index.md","filePath":"garden/digital-gardens/index.md"}'),c={name:"garden/digital-gardens/index.md"},x=Object.assign(c,{setup(m){const r=n();return(f,u)=>(o(),d("div",null,[s,e("p",null,[i("67 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,g)]),h]))}});export{_ as __pageData,x as default}; diff --git a/assets/garden_digital-locality_index.md.zReLaiCJ.js b/assets/garden_digital-locality_index.md.CqP1_XyW.js similarity index 99% rename from assets/garden_digital-locality_index.md.zReLaiCJ.js rename to assets/garden_digital-locality_index.md.CqP1_XyW.js index bc9692524..71a128adb 100644 --- a/assets/garden_digital-locality_index.md.zReLaiCJ.js +++ b/assets/garden_digital-locality_index.md.CqP1_XyW.js @@ -1 +1 @@ -import{d as o}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as r,Q as e,K as n,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Digital Locality",-1),d=["innerHTML"],c=s('
Referenced by:"No Politics" RulesChromatic LatticeDecentralized ModerationFilter BubblesSocial MediaVirality

A locality is a physical area or neighborhood where people live and regularly see each other. In the same way I believe strong Local Communities are highly important in real life, I think Social Media would benefit from having digital localities.

A digital locality will have a higher concentration of recognition between its members, leading to more meaningful relationships. This is achieved by operating similar to a physical neighborhood, where you're able to "look outside" and perhaps see a couple neighbors quite regularly, but with additional effort you can always "walk" further and further out to see a larger variety of people, and similarly others may "walk" to find you. This makes individual reach rely on a gradient of effort, keeping influence spread thin.

The motivations behind digital locality are aligned with the findings of Dunbar and his research on the cognitive limit for how many people we can maintain meaningful relationships with. He discusses his research and how it's held up over the years in this article.

Important Aspects

Porosity

The most important aspect of digital locality should be that one's neighborhood has no discrete walls, only continuous gradients. For example, if our goal was merely small communities where you see the same people regularly, any small discord server would fit the bill. But in discord if you want to reach out to "nearby" users, you have to join an entire new discord server. In other words, communities on discord are not "porous", letting users freely "leak" between each other. The neighborhood metaphor for digital locality would mean having no discrete walls around any community, thus being fully "porous". This allows you to more easily expand your network and meet people with whom to form meaningful relationships.

Decentralization

A large motivation behind this concept is spreading influence thin. In the same way digital locality directly opposes the centralization of influence in the hands of the few, it opposes all sorts of centralization. Centralized ownership and moderation over the network leaves it vulnerable to Enshittification and other problems. In practice, this means such a network should be Decentralized, ideally built on something like the Agentic Fediverse.

Social media must be moderated, which means a network with digital locality will need Decentralized Moderation. There's several approaches discussed there, but ultimately the way digital locality works should overall mean users are significantly less likely to see unwanted content from influencers, advertisers, bots, spammers, or those who wish them harm. Users won't need to worry about their post going viral leading to a very large and unexpected amount of attention, including negative attention, directed their way.

Democratized Virality

A network with digital locality would make individual people or posts have limited reach, and thus prevent those from "going viral". However, movements and ideas can still spread largely uninhibited, and even empower individuals to help spread the movement moreso than traditional social media. They can put more effort into being heard by moving further and further out through the network, whereas on traditional social media you can only hope the algorithm spreads your post.

Synchronous vs Asynchronous Interactions

Exactly how such a network looks and behaves will differ based on if it's going for synchronous vs asynchronous communication. Synchronous is the easier one, as that's essentially just a network of chat rooms with links to other chat rooms. Users explore the network through those links and just have realtime conversations with the people they find.

Asynchronous interactions are a bit trickier, and I'm not fully convinced on how it should work. It'll be important to work this out since that's how a lot of social media operates - any social media where you make posts, essentially. We'll go over a couple approaches to how it could work, keeping mind neither are perfect.

Local Feeds

Having a feed of posts that's just those you follow and the stuff they've liked or shared works fairly well and can be done today in most existing social media apps. However, seeing the exact post that has gone through a very long chain of shares to get to you means the author of that post may be receiving more attention than they desired. Additionally, this method may not have enough throughout if you read a lot of posts or don't follow active people.

The network of vouches approach to Decentralized Moderation sort of expands on this type of feed, giving the user content from longer following chains and much more control over who is let into the network. It's also auditable, unlike algorithmic feeds.

Communal wiki editing

A more radical approach would be treating social media more like communal wiki editing. That is, if engaging with a post was, rather than liking or sharing it, proposing edits to communal wiki pages it relates to. This would be a process of message gardening, and would likely help distributing corrections to articles, which typically spread much less far than the original incorrect information. It's for that reason I brought this idea up at the end of Filter Bubbles as a potential way to combat the spread of misinformation.

However, wiki editing requires a lot more effort than liking or sharing currently does. It's also not clear how this would preserve locality without making discrete communities. Commune is related to this idea but would have discrete communities (although with a bit of porosity through shared channels). Perhaps discrete communities could be avoided by allowing anyone to create pages, but then allow them to enter Anarchist collectives that manage the page together. Anyone (or perhaps those within a network of vouches) can comment or propose edits to it, and through that the information spreads to members and anyone else who follows that page.

Obstacles

The Network Effect

The biggest obstacle, as with any alternative social media, is the network effect. People want to be on a platform that's already popular, thus preserving the status quo. Social Media typically succeeds by enabling some new medium, like Twitter for microplogging, vine for videos (and later Snapchat once vine shut down), or Musically for lip syncing. The exceptions are existing platforms with large user bases expanding into one of those new mediums, like Instagram or Musically rebranding as Tiktok.

There's an issue here, though. I'm not describing a new medium here. The unique selling point is that by limiting influence accumulation and making it so you're more likely to see the same not-popular people regularly, we're actually fighting against part of what makes social media interesting for so many people: the concept of this meritocratic space where anyone can become a celebrity if they just make good enough content. That it could become a job, even, where they get paid a lot to make content and receive free stuff and other perks for doing so. This is the classic American Dream argument that American culture has already been conditioned into supporting. So success for this platform may hinge on convincing people becoming a social media influencer is not a good thing to strive for, both for how unhealthy the mindset is, and how unlikely it is for any individual to "make it". Needless to say, that's a very tall order.

Avoiding Filter Bubbles (or Echo Chambers)

An anticipated argument against what I'm describing here is that it would encourage the creation of filter bubbles. But I'd like to counter that argument by saying you're tackling the wrong issue, and that filter bubbles are typically innocuous and abolishing them would be actively harmful to marginalized communities. Indeed, I think digital locality would help fight against a lot of the root problems that are often attributes to echo chambers, as I describe on the Filter Bubbles page .

Influences

Webrings

Erlend discusses a similar concept to locality in his blog post Federated Webrings, which describes how the old internet would make frequent use of webrings to connect similar sites. This would effectively create digital neighbors and make both the site owner and visitors connect with the owners and visitors of the other sites in the webring. Although I think these webrings become a bit too large and centralized. I would've preferred to see them work more like cooperatives, with some form of democratic decision making.

Erlend's suggestion for bringing webrings back is through the use of communities using shared topic-specific rooms. For example, several rust game development libraries having a shared chatroom for discussing game development in general. This makes the communities more porous, so members can discover related people and communities.

I recommend reading through the rest of Erlend's writing and keeping up with their projects. They've done a lot in this sphere, both while working at discourse and since, and are leading the charge for designing and implementing the agentic fediverse.

IndieWeb

Personal websites form a fully decentralized social network called the indie web, which focuses on data ownership. However, it's quite small due to the technical and financial barriers to creating a website. Due to the lack of centralization or algorithms, sites spread primarily by being linked to by others. That brings it close to what I'm describing here, although without asynchronous chat I don't think it's quite what I'm looking for.

MUDs

What I'm describing is also a lot like a MUD, classic online games where players existed in a world of connected rooms, where they interacted via a command line interface, including local and global chat. If it were decentralized and people all had control over their own room, it would look a lot like what I am describing (but much nerdier and less modern). It's a big inspiration for a lot of these ideas.

Where to Start

There are so many competing protocols out there at the moment, and the network effect has made them all struggle to find a foothold. I don't think anything described in here would be the unique selling point to just immediately attract a large user base. With that in mind, I think the approach should be to make something thats with using for reasons other than social media, and attach the social media experiment to it. That can serve as a proof of concept to prove the ideas here work, although ideas that don't work to be iterated upon, and collect public interest in whatever the next step is.

With the above in mind, let me introduce Chromatic Lattice, an incremental game I've been designing that would need social features to work anyways. Specifically, it will have boards for each player, where the actual gameplay happens. These boards can be linked to publicly, so you can show off your boards. When a player is visiting someone else's board, their cursor will be visible to others there, and their will be local chat to just people on that page, a form of ambient copresence. These boards can be customized, including links to other boards. Thus locality is introduced - we now have synchronous chat rooms that every player has, and they can explore the network by jumping through these links. There are more details on the chromatic lattice page.

',40),w=JSON.parse('{"title":"Digital Locality","description":"","frontmatter":{"public":"true","slug":"digital-locality","title":"Digital Locality","prev":false,"next":false},"headers":[],"relativePath":"garden/digital-locality/index.md","filePath":"garden/digital-locality/index.md"}'),u={name:"garden/digital-locality/index.md"},y=Object.assign(u,{setup(m){const t=i();return(g,p)=>(l(),r("div",null,[h,e("p",null,[n("1803 words, ~10 minute read. "),e("span",{innerHTML:a(o)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),c]))}});export{w as __pageData,y as default}; +import{d as o}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as r,Q as e,K as n,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Digital Locality",-1),d=["innerHTML"],c=s('
Referenced by:"No Politics" RulesChromatic LatticeDecentralized ModerationFilter BubblesSocial MediaVirality

A locality is a physical area or neighborhood where people live and regularly see each other. In the same way I believe strong Local Communities are highly important in real life, I think Social Media would benefit from having digital localities.

A digital locality will have a higher concentration of recognition between its members, leading to more meaningful relationships. This is achieved by operating similar to a physical neighborhood, where you're able to "look outside" and perhaps see a couple neighbors quite regularly, but with additional effort you can always "walk" further and further out to see a larger variety of people, and similarly others may "walk" to find you. This makes individual reach rely on a gradient of effort, keeping influence spread thin.

The motivations behind digital locality are aligned with the findings of Dunbar and his research on the cognitive limit for how many people we can maintain meaningful relationships with. He discusses his research and how it's held up over the years in this article.

Important Aspects

Porosity

The most important aspect of digital locality should be that one's neighborhood has no discrete walls, only continuous gradients. For example, if our goal was merely small communities where you see the same people regularly, any small discord server would fit the bill. But in discord if you want to reach out to "nearby" users, you have to join an entire new discord server. In other words, communities on discord are not "porous", letting users freely "leak" between each other. The neighborhood metaphor for digital locality would mean having no discrete walls around any community, thus being fully "porous". This allows you to more easily expand your network and meet people with whom to form meaningful relationships.

Decentralization

A large motivation behind this concept is spreading influence thin. In the same way digital locality directly opposes the centralization of influence in the hands of the few, it opposes all sorts of centralization. Centralized ownership and moderation over the network leaves it vulnerable to Enshittification and other problems. In practice, this means such a network should be Decentralized, ideally built on something like the Agentic Fediverse.

Social media must be moderated, which means a network with digital locality will need Decentralized Moderation. There's several approaches discussed there, but ultimately the way digital locality works should overall mean users are significantly less likely to see unwanted content from influencers, advertisers, bots, spammers, or those who wish them harm. Users won't need to worry about their post going viral leading to a very large and unexpected amount of attention, including negative attention, directed their way.

Democratized Virality

A network with digital locality would make individual people or posts have limited reach, and thus prevent those from "going viral". However, movements and ideas can still spread largely uninhibited, and even empower individuals to help spread the movement moreso than traditional social media. They can put more effort into being heard by moving further and further out through the network, whereas on traditional social media you can only hope the algorithm spreads your post.

Synchronous vs Asynchronous Interactions

Exactly how such a network looks and behaves will differ based on if it's going for synchronous vs asynchronous communication. Synchronous is the easier one, as that's essentially just a network of chat rooms with links to other chat rooms. Users explore the network through those links and just have realtime conversations with the people they find.

Asynchronous interactions are a bit trickier, and I'm not fully convinced on how it should work. It'll be important to work this out since that's how a lot of social media operates - any social media where you make posts, essentially. We'll go over a couple approaches to how it could work, keeping mind neither are perfect.

Local Feeds

Having a feed of posts that's just those you follow and the stuff they've liked or shared works fairly well and can be done today in most existing social media apps. However, seeing the exact post that has gone through a very long chain of shares to get to you means the author of that post may be receiving more attention than they desired. Additionally, this method may not have enough throughout if you read a lot of posts or don't follow active people.

The network of vouches approach to Decentralized Moderation sort of expands on this type of feed, giving the user content from longer following chains and much more control over who is let into the network. It's also auditable, unlike algorithmic feeds.

Communal wiki editing

A more radical approach would be treating social media more like communal wiki editing. That is, if engaging with a post was, rather than liking or sharing it, proposing edits to communal wiki pages it relates to. This would be a process of message gardening, and would likely help distributing corrections to articles, which typically spread much less far than the original incorrect information. It's for that reason I brought this idea up at the end of Filter Bubbles as a potential way to combat the spread of misinformation.

However, wiki editing requires a lot more effort than liking or sharing currently does. It's also not clear how this would preserve locality without making discrete communities. Commune is related to this idea but would have discrete communities (although with a bit of porosity through shared channels). Perhaps discrete communities could be avoided by allowing anyone to create pages, but then allow them to enter Anarchist collectives that manage the page together. Anyone (or perhaps those within a network of vouches) can comment or propose edits to it, and through that the information spreads to members and anyone else who follows that page.

Obstacles

The Network Effect

The biggest obstacle, as with any alternative social media, is the network effect. People want to be on a platform that's already popular, thus preserving the status quo. Social Media typically succeeds by enabling some new medium, like Twitter for microplogging, vine for videos (and later Snapchat once vine shut down), or Musically for lip syncing. The exceptions are existing platforms with large user bases expanding into one of those new mediums, like Instagram or Musically rebranding as Tiktok.

There's an issue here, though. I'm not describing a new medium here. The unique selling point is that by limiting influence accumulation and making it so you're more likely to see the same not-popular people regularly, we're actually fighting against part of what makes social media interesting for so many people: the concept of this meritocratic space where anyone can become a celebrity if they just make good enough content. That it could become a job, even, where they get paid a lot to make content and receive free stuff and other perks for doing so. This is the classic American Dream argument that American culture has already been conditioned into supporting. So success for this platform may hinge on convincing people becoming a social media influencer is not a good thing to strive for, both for how unhealthy the mindset is, and how unlikely it is for any individual to "make it". Needless to say, that's a very tall order.

Avoiding Filter Bubbles (or Echo Chambers)

An anticipated argument against what I'm describing here is that it would encourage the creation of filter bubbles. But I'd like to counter that argument by saying you're tackling the wrong issue, and that filter bubbles are typically innocuous and abolishing them would be actively harmful to marginalized communities. Indeed, I think digital locality would help fight against a lot of the root problems that are often attributes to echo chambers, as I describe on the Filter Bubbles page .

Influences

Webrings

Erlend discusses a similar concept to locality in his blog post Federated Webrings, which describes how the old internet would make frequent use of webrings to connect similar sites. This would effectively create digital neighbors and make both the site owner and visitors connect with the owners and visitors of the other sites in the webring. Although I think these webrings become a bit too large and centralized. I would've preferred to see them work more like cooperatives, with some form of democratic decision making.

Erlend's suggestion for bringing webrings back is through the use of communities using shared topic-specific rooms. For example, several rust game development libraries having a shared chatroom for discussing game development in general. This makes the communities more porous, so members can discover related people and communities.

I recommend reading through the rest of Erlend's writing and keeping up with their projects. They've done a lot in this sphere, both while working at discourse and since, and are leading the charge for designing and implementing the agentic fediverse.

IndieWeb

Personal websites form a fully decentralized social network called the indie web, which focuses on data ownership. However, it's quite small due to the technical and financial barriers to creating a website. Due to the lack of centralization or algorithms, sites spread primarily by being linked to by others. That brings it close to what I'm describing here, although without asynchronous chat I don't think it's quite what I'm looking for.

MUDs

What I'm describing is also a lot like a MUD, classic online games where players existed in a world of connected rooms, where they interacted via a command line interface, including local and global chat. If it were decentralized and people all had control over their own room, it would look a lot like what I am describing (but much nerdier and less modern). It's a big inspiration for a lot of these ideas.

Where to Start

There are so many competing protocols out there at the moment, and the network effect has made them all struggle to find a foothold. I don't think anything described in here would be the unique selling point to just immediately attract a large user base. With that in mind, I think the approach should be to make something thats with using for reasons other than social media, and attach the social media experiment to it. That can serve as a proof of concept to prove the ideas here work, although ideas that don't work to be iterated upon, and collect public interest in whatever the next step is.

With the above in mind, let me introduce Chromatic Lattice, an incremental game I've been designing that would need social features to work anyways. Specifically, it will have boards for each player, where the actual gameplay happens. These boards can be linked to publicly, so you can show off your boards. When a player is visiting someone else's board, their cursor will be visible to others there, and their will be local chat to just people on that page, a form of ambient copresence. These boards can be customized, including links to other boards. Thus locality is introduced - we now have synchronous chat rooms that every player has, and they can explore the network by jumping through these links. There are more details on the chromatic lattice page.

',40),w=JSON.parse('{"title":"Digital Locality","description":"","frontmatter":{"public":"true","slug":"digital-locality","title":"Digital Locality","prev":false,"next":false},"headers":[],"relativePath":"garden/digital-locality/index.md","filePath":"garden/digital-locality/index.md"}'),u={name:"garden/digital-locality/index.md"},y=Object.assign(u,{setup(m){const t=i();return(g,p)=>(l(),r("div",null,[h,e("p",null,[n("1803 words, ~10 minute read. "),e("span",{innerHTML:a(o)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),c]))}});export{w as __pageData,y as default}; diff --git a/assets/garden_digital-locality_index.md.zReLaiCJ.lean.js b/assets/garden_digital-locality_index.md.CqP1_XyW.lean.js similarity index 91% rename from assets/garden_digital-locality_index.md.zReLaiCJ.lean.js rename to assets/garden_digital-locality_index.md.CqP1_XyW.lean.js index c54d0f523..ea1163f5a 100644 --- a/assets/garden_digital-locality_index.md.zReLaiCJ.lean.js +++ b/assets/garden_digital-locality_index.md.CqP1_XyW.lean.js @@ -1 +1 @@ -import{d as o}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as r,Q as e,K as n,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Digital Locality",-1),d=["innerHTML"],c=s("",40),w=JSON.parse('{"title":"Digital Locality","description":"","frontmatter":{"public":"true","slug":"digital-locality","title":"Digital Locality","prev":false,"next":false},"headers":[],"relativePath":"garden/digital-locality/index.md","filePath":"garden/digital-locality/index.md"}'),u={name:"garden/digital-locality/index.md"},y=Object.assign(u,{setup(m){const t=i();return(g,p)=>(l(),r("div",null,[h,e("p",null,[n("1803 words, ~10 minute read. "),e("span",{innerHTML:a(o)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),c]))}});export{w as __pageData,y as default}; +import{d as o}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as r,Q as e,K as n,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Digital Locality",-1),d=["innerHTML"],c=s("",40),w=JSON.parse('{"title":"Digital Locality","description":"","frontmatter":{"public":"true","slug":"digital-locality","title":"Digital Locality","prev":false,"next":false},"headers":[],"relativePath":"garden/digital-locality/index.md","filePath":"garden/digital-locality/index.md"}'),u={name:"garden/digital-locality/index.md"},y=Object.assign(u,{setup(m){const t=i();return(g,p)=>(l(),r("div",null,[h,e("p",null,[n("1803 words, ~10 minute read. "),e("span",{innerHTML:a(o)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),c]))}});export{w as __pageData,y as default}; diff --git a/assets/garden_direct-democracy_index.md.DYir6dY7.js b/assets/garden_direct-democracy_index.md.Drd3bOt8.js similarity index 95% rename from assets/garden_direct-democracy_index.md.DYir6dY7.js rename to assets/garden_direct-democracy_index.md.Drd3bOt8.js index 4380ebe43..de19225a1 100644 --- a/assets/garden_direct-democracy_index.md.DYir6dY7.js +++ b/assets/garden_direct-democracy_index.md.Drd3bOt8.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as o,Q as e,K as s,u as r,p as c}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"Direct Democracy",-1),d=["innerHTML"],m=e("hr",null,null,-1),l=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/anarchism/index.md"},"Anarchism"),e("a",{href:"/garden/consensus-democracy/index.md"},"Consensus Democracy"),e("a",{href:"/garden/gerrymandering/index.md"},"Gerrymandering")],-1),u=e("p",null,"A form of democracy where every voter gets to vote on every issue directly, and the majority rules. This form of voting is often criticized for having no safe guards to prevent a majority group from oppressing a minority group.",-1),v=JSON.parse('{"title":"Direct Democracy","description":"","frontmatter":{"alias":"Mob Rule, Tyranny of the Majority","public":"true","slug":"direct-democracy","title":"Direct Democracy","prev":false,"next":false},"headers":[],"relativePath":"garden/direct-democracy/index.md","filePath":"garden/direct-democracy/index.md"}'),p={name:"garden/direct-democracy/index.md"},x=Object.assign(p,{setup(f){const a=n();return(y,h)=>(c(),o("div",null,[i,e("p",null,[s("40 words, ~0 minute read. "),e("span",{innerHTML:r(t)[`site/${r(a).page.value.relativePath}`]},null,8,d)]),m,l,u]))}});export{v as __pageData,x as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as o,Q as e,K as s,u as r,p as c}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"Direct Democracy",-1),d=["innerHTML"],m=e("hr",null,null,-1),l=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/anarchism/index.md"},"Anarchism"),e("a",{href:"/garden/consensus-democracy/index.md"},"Consensus Democracy"),e("a",{href:"/garden/gerrymandering/index.md"},"Gerrymandering")],-1),u=e("p",null,"A form of democracy where every voter gets to vote on every issue directly, and the majority rules. This form of voting is often criticized for having no safe guards to prevent a majority group from oppressing a minority group.",-1),v=JSON.parse('{"title":"Direct Democracy","description":"","frontmatter":{"alias":"Mob Rule, Tyranny of the Majority","public":"true","slug":"direct-democracy","title":"Direct Democracy","prev":false,"next":false},"headers":[],"relativePath":"garden/direct-democracy/index.md","filePath":"garden/direct-democracy/index.md"}'),p={name:"garden/direct-democracy/index.md"},x=Object.assign(p,{setup(f){const a=n();return(y,h)=>(c(),o("div",null,[i,e("p",null,[s("40 words, ~0 minute read. "),e("span",{innerHTML:r(t)[`site/${r(a).page.value.relativePath}`]},null,8,d)]),m,l,u]))}});export{v as __pageData,x as default}; diff --git a/assets/garden_direct-democracy_index.md.DYir6dY7.lean.js b/assets/garden_direct-democracy_index.md.Drd3bOt8.lean.js similarity index 95% rename from assets/garden_direct-democracy_index.md.DYir6dY7.lean.js rename to assets/garden_direct-democracy_index.md.Drd3bOt8.lean.js index 4380ebe43..de19225a1 100644 --- a/assets/garden_direct-democracy_index.md.DYir6dY7.lean.js +++ b/assets/garden_direct-democracy_index.md.Drd3bOt8.lean.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as o,Q as e,K as s,u as r,p as c}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"Direct Democracy",-1),d=["innerHTML"],m=e("hr",null,null,-1),l=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/anarchism/index.md"},"Anarchism"),e("a",{href:"/garden/consensus-democracy/index.md"},"Consensus Democracy"),e("a",{href:"/garden/gerrymandering/index.md"},"Gerrymandering")],-1),u=e("p",null,"A form of democracy where every voter gets to vote on every issue directly, and the majority rules. This form of voting is often criticized for having no safe guards to prevent a majority group from oppressing a minority group.",-1),v=JSON.parse('{"title":"Direct Democracy","description":"","frontmatter":{"alias":"Mob Rule, Tyranny of the Majority","public":"true","slug":"direct-democracy","title":"Direct Democracy","prev":false,"next":false},"headers":[],"relativePath":"garden/direct-democracy/index.md","filePath":"garden/direct-democracy/index.md"}'),p={name:"garden/direct-democracy/index.md"},x=Object.assign(p,{setup(f){const a=n();return(y,h)=>(c(),o("div",null,[i,e("p",null,[s("40 words, ~0 minute read. "),e("span",{innerHTML:r(t)[`site/${r(a).page.value.relativePath}`]},null,8,d)]),m,l,u]))}});export{v as __pageData,x as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as o,Q as e,K as s,u as r,p as c}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"Direct Democracy",-1),d=["innerHTML"],m=e("hr",null,null,-1),l=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/anarchism/index.md"},"Anarchism"),e("a",{href:"/garden/consensus-democracy/index.md"},"Consensus Democracy"),e("a",{href:"/garden/gerrymandering/index.md"},"Gerrymandering")],-1),u=e("p",null,"A form of democracy where every voter gets to vote on every issue directly, and the majority rules. This form of voting is often criticized for having no safe guards to prevent a majority group from oppressing a minority group.",-1),v=JSON.parse('{"title":"Direct Democracy","description":"","frontmatter":{"alias":"Mob Rule, Tyranny of the Majority","public":"true","slug":"direct-democracy","title":"Direct Democracy","prev":false,"next":false},"headers":[],"relativePath":"garden/direct-democracy/index.md","filePath":"garden/direct-democracy/index.md"}'),p={name:"garden/direct-democracy/index.md"},x=Object.assign(p,{setup(f){const a=n();return(y,h)=>(c(),o("div",null,[i,e("p",null,[s("40 words, ~0 minute read. "),e("span",{innerHTML:r(t)[`site/${r(a).page.value.relativePath}`]},null,8,d)]),m,l,u]))}});export{v as __pageData,x as default}; diff --git a/assets/garden_enshittification_index.md.B1b1fu7S.js b/assets/garden_enshittification_index.md.DPNqV21w.js similarity index 96% rename from assets/garden_enshittification_index.md.B1b1fu7S.js rename to assets/garden_enshittification_index.md.DPNqV21w.js index 9278d9a2d..06e7e098c 100644 --- a/assets/garden_enshittification_index.md.B1b1fu7S.js +++ b/assets/garden_enshittification_index.md.DPNqV21w.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as r,Q as e,K as t,u as i,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Enshittification",-1),c=["innerHTML"],d=e("hr",null,null,-1),h=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/decentralized/index.md"},"Decentralized"),e("a",{href:"/garden/digital-locality/index.md"},"Digital Locality"),e("a",{href:"/garden/the-small-web/index.md"},"The Small Web")],-1),m=e("p",null,[t("Large websites are expensive to operate and are typically owned by corporations. The profit motive of capitalism states that these websites must continuously be trying to make more money, which means if they're not growing users, they must increase how much they're making per user. This process means corporate backed websites become worse for their users over time, which Cory Doctorow coined as "),e("a",{href:"https://pluralistic.net/2023/01/21/potemkin-ai/",target:"_blank",rel:"noreferrer"},"Enshittification"),t(".")],-1),b=JSON.parse('{"title":"Enshittification","description":"","frontmatter":{"alias":"Enshittify","public":"true","slug":"enshittification","title":"Enshittification","prev":false,"next":false},"headers":[],"relativePath":"garden/enshittification/index.md","filePath":"garden/enshittification/index.md"}'),p={name:"garden/enshittification/index.md"},w=Object.assign(p,{setup(u){const a=s();return(f,_)=>(o(),r("div",null,[l,e("p",null,[t("66 words, ~0 minute read. "),e("span",{innerHTML:i(n)[`site/${i(a).page.value.relativePath}`]},null,8,c)]),d,h,m]))}});export{b as __pageData,w as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as r,Q as e,K as t,u as i,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Enshittification",-1),c=["innerHTML"],d=e("hr",null,null,-1),h=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/decentralized/index.md"},"Decentralized"),e("a",{href:"/garden/digital-locality/index.md"},"Digital Locality"),e("a",{href:"/garden/the-small-web/index.md"},"The Small Web")],-1),m=e("p",null,[t("Large websites are expensive to operate and are typically owned by corporations. The profit motive of capitalism states that these websites must continuously be trying to make more money, which means if they're not growing users, they must increase how much they're making per user. This process means corporate backed websites become worse for their users over time, which Cory Doctorow coined as "),e("a",{href:"https://pluralistic.net/2023/01/21/potemkin-ai/",target:"_blank",rel:"noreferrer"},"Enshittification"),t(".")],-1),b=JSON.parse('{"title":"Enshittification","description":"","frontmatter":{"alias":"Enshittify","public":"true","slug":"enshittification","title":"Enshittification","prev":false,"next":false},"headers":[],"relativePath":"garden/enshittification/index.md","filePath":"garden/enshittification/index.md"}'),p={name:"garden/enshittification/index.md"},w=Object.assign(p,{setup(u){const a=s();return(f,_)=>(o(),r("div",null,[l,e("p",null,[t("66 words, ~0 minute read. "),e("span",{innerHTML:i(n)[`site/${i(a).page.value.relativePath}`]},null,8,c)]),d,h,m]))}});export{b as __pageData,w as default}; diff --git a/assets/garden_enshittification_index.md.B1b1fu7S.lean.js b/assets/garden_enshittification_index.md.DPNqV21w.lean.js similarity index 96% rename from assets/garden_enshittification_index.md.B1b1fu7S.lean.js rename to assets/garden_enshittification_index.md.DPNqV21w.lean.js index 9278d9a2d..06e7e098c 100644 --- a/assets/garden_enshittification_index.md.B1b1fu7S.lean.js +++ b/assets/garden_enshittification_index.md.DPNqV21w.lean.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as r,Q as e,K as t,u as i,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Enshittification",-1),c=["innerHTML"],d=e("hr",null,null,-1),h=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/decentralized/index.md"},"Decentralized"),e("a",{href:"/garden/digital-locality/index.md"},"Digital Locality"),e("a",{href:"/garden/the-small-web/index.md"},"The Small Web")],-1),m=e("p",null,[t("Large websites are expensive to operate and are typically owned by corporations. The profit motive of capitalism states that these websites must continuously be trying to make more money, which means if they're not growing users, they must increase how much they're making per user. This process means corporate backed websites become worse for their users over time, which Cory Doctorow coined as "),e("a",{href:"https://pluralistic.net/2023/01/21/potemkin-ai/",target:"_blank",rel:"noreferrer"},"Enshittification"),t(".")],-1),b=JSON.parse('{"title":"Enshittification","description":"","frontmatter":{"alias":"Enshittify","public":"true","slug":"enshittification","title":"Enshittification","prev":false,"next":false},"headers":[],"relativePath":"garden/enshittification/index.md","filePath":"garden/enshittification/index.md"}'),p={name:"garden/enshittification/index.md"},w=Object.assign(p,{setup(u){const a=s();return(f,_)=>(o(),r("div",null,[l,e("p",null,[t("66 words, ~0 minute read. "),e("span",{innerHTML:i(n)[`site/${i(a).page.value.relativePath}`]},null,8,c)]),d,h,m]))}});export{b as __pageData,w as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as r,Q as e,K as t,u as i,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Enshittification",-1),c=["innerHTML"],d=e("hr",null,null,-1),h=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/decentralized/index.md"},"Decentralized"),e("a",{href:"/garden/digital-locality/index.md"},"Digital Locality"),e("a",{href:"/garden/the-small-web/index.md"},"The Small Web")],-1),m=e("p",null,[t("Large websites are expensive to operate and are typically owned by corporations. The profit motive of capitalism states that these websites must continuously be trying to make more money, which means if they're not growing users, they must increase how much they're making per user. This process means corporate backed websites become worse for their users over time, which Cory Doctorow coined as "),e("a",{href:"https://pluralistic.net/2023/01/21/potemkin-ai/",target:"_blank",rel:"noreferrer"},"Enshittification"),t(".")],-1),b=JSON.parse('{"title":"Enshittification","description":"","frontmatter":{"alias":"Enshittify","public":"true","slug":"enshittification","title":"Enshittification","prev":false,"next":false},"headers":[],"relativePath":"garden/enshittification/index.md","filePath":"garden/enshittification/index.md"}'),p={name:"garden/enshittification/index.md"},w=Object.assign(p,{setup(u){const a=s();return(f,_)=>(o(),r("div",null,[l,e("p",null,[t("66 words, ~0 minute read. "),e("span",{innerHTML:i(n)[`site/${i(a).page.value.relativePath}`]},null,8,c)]),d,h,m]))}});export{b as __pageData,w as default}; diff --git a/assets/garden_everything-is-political_index.md.CdBgMXxj.js b/assets/garden_everything-is-political_index.md.rbSDwqZc.js similarity index 99% rename from assets/garden_everything-is-political_index.md.CdBgMXxj.js rename to assets/garden_everything-is-political_index.md.rbSDwqZc.js index cb2de8e24..fcf69939e 100644 --- a/assets/garden_everything-is-political_index.md.CdBgMXxj.js +++ b/assets/garden_everything-is-political_index.md.rbSDwqZc.js @@ -1 +1 @@ -import{d as a}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as s,Q as e,K as n,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Everything is Political",-1),c=["innerHTML"],p=r('
Referenced by:"No Politics" Rules

Politics shape every facet of our lives, but its influence is often so entrenched it becomes invisible unless you're actively trying to be conscious of it. But being conscious of it is important, because otherwise you'll just end up implicitly supporting the current power structures created and maintained by the political status quo. Or society has guided us towards considering much of it as apolitical when is not for the purpose of perpetuating the existing power structures (capitalism, patriarchy, and white supremacy).

Consumption is political

We live in a society dictated by capitalism, and it has infiltrated not only our markets but every aspect of our lives. We all know when you buy an apple from the store not all of it goes to the workers; it's putting some amount of money in capitalists' pockets and further accumulating wealth at the top of the hierarchy. We know the prices are only as low as they are due to the exploitation of workers all around the world working in horrible conditions for horrible pay. We know the company we buy from is organized like a totalitarian regime where all the decisions come from up high and serve to benefit those at the top. So why isn't buying an apple political?

Engaging in our market economy is both a necessity for our survival, and normalized through decades and decades of propaganda and reinforcement of the status quo. We become alienated to the effects of our actions as a defense measure because our daily complicity in various atrocities are simply too grand to carry on our shoulders. It becomes apolitical out of necessity. This has a side effect of making all challenges to the status quo (progressivism) appear far more controversial and political than just keeping things as they are.

With so many things becoming commodified, this effect becomes stronger with time. Our culture, love, attention have all been commodified. Everything being for sale means politics affects everything.

The Search For The Apolitical Video Game goes over how essentially everything is political, through the framework of searching for an "apolitical" video game. The arguments they make for video games trivially apply to all forms of media. If all media is political, so is the act of consuming it. Even news will always have a bias, as Objectivity doesn't exist.

r/NonPoliticalTwitter

This is a subreddit that claims to only allow non-political content. Naturally, this is a good case study to argue why the concept of non-political content doesn't exist. They have an interesting interpretation of politics, wherein content can even involve political figures, if the focus of the post isn't considered political. This leads to one of the top posts at the time of writing being about Jimmy Carter giving a speech in Japan. So its a post about a US president engaging in politics abroad, but the post focuses on how an interpreter handled a joke, so it's not political. There's naturally no discussion on why Carter was in Japan or putting this event in a broader context of the relationship between the US and Japan after WW2 and Carter's role in repairing it.

Even when they don't involve US presidents, nearly every post on that subreddit can be associated with politics. Complaining about subscription costs and how support agents can reduce the prices to keep you from leaving is apolitical, as is discussing how childrens cereal is so unhealthy ants disregard it as food. Apparently criticizing the lies told to us by our education system is apolitical, just like voicing distaste with how much advertising corporations spam. These are political issues, and they're only able to pass as apolitical by maintaining a lack of awareness on how politics shape society.

Inaction is political

There is no "apolitical" perspective, as that's really just the stance of maintaining the political status quo. As put by Angela Davis, "In a racist society it is not enough to be non-racist, we must be anti-racist." Essentially, politics affect all of us and everything is political, and if you believe politics don't effect you, that's probably because the current political and economic systems work in your favor.

How to radicalize a normie describes how communities can be overtaken by fascists exploiting the fact that statements that are deemed "apolitical" are the ones with consensus, coupled with the fact that progressive statements, by challenging the status quo, are not going to have consensus in communities without a political alignment.

Centrism has no merit

Adjacent to people seeking to avoid politics outright are those who hold the belief that our two parties are on polar extremes and hold the belief the correct position is going to be somewhere in the middle, taking aspects of both parties. This is fallacious because the center has no special value that makes it better than the extremes, a lot of the issues centrists want to pull from the different parties never needed to be politicized in the first place, and the two US parties are not on polar extremes anyways.

The center is just the midpoint between two points. That's it. Rejecting both sides doesn't make you intellectually or morally superior. The horseshoe theory was never a good theory to begin with, with the underlying political philosophies between the two sides being fundamentally opposed. I recommend "Blackshirts and Reds" by Michael Parenti if you'd like a better understanding of why the two ideologies are polar opposites, and how they clashed.

In practice these midpoints don't even make much sense to uphold. If the left says trans people should not be discriminated against, and the right says they shouldn't exist, where's the midpoint? We should discriminate against trans people but allow them to exist? Oh, how kind. In practice this is literally the stance liberals take, though: trans people can exist, but how dare you support Trans athletes in sports!

Today, centrism in America is not even talking about the midpoint between the rightist and leftist ideologies, but rather the Republicans and Democrats. These are arbitrary points dictated by the Overton Window that make the midpoint even more arbitrary. What is the midpoint between socialism and capitalism? The former is defined by private property not existing, the latter the opposite. Any midpoint is clearly still just capitalism, just with some regulations to temporarily stave off crises caused by capitalism's contradictions. The two US parties are both in defense of private ownership of the means of production, so the midpoint was never really going to be anywhere close to the left. This is why Bernie Sanders was called a "true" centrist because, by being further left than the Democrats, he actually was closer to whatever the actual midpoint between the far left and far right would be. Even then, the other arguments against centrism still apply.

Like political apathy, centrism is really just a bias towards the status quo, which I shall remind you is shaped by unjust power structures like capitalism, patriarchy, and white supremacy. All my arguments, both here and in my page against "No Politics" Rules, apply equally to centrists as they do the politically apathetic. The Angela Davis quote once again comes to mind: "In a racist society it is not enough to be non-racist, we must be anti-racist."

',20),w=JSON.parse('{"title":"Everything is Political","description":"","frontmatter":{"public":"true","slug":"everything-is-political","title":"Everything is Political","prev":false,"next":false},"headers":[],"relativePath":"garden/everything-is-political/index.md","filePath":"garden/everything-is-political/index.md"}'),u={name:"garden/everything-is-political/index.md"},b=Object.assign(u,{setup(d){const i=o();return(m,f)=>(l(),s("div",null,[h,e("p",null,[n("1100 words, ~6 minute read. "),e("span",{innerHTML:t(a)[`site/${t(i).page.value.relativePath}`]},null,8,c)]),p]))}});export{w as __pageData,b as default}; +import{d as a}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as s,Q as e,K as n,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Everything is Political",-1),c=["innerHTML"],p=r('
Referenced by:"No Politics" Rules

Politics shape every facet of our lives, but its influence is often so entrenched it becomes invisible unless you're actively trying to be conscious of it. But being conscious of it is important, because otherwise you'll just end up implicitly supporting the current power structures created and maintained by the political status quo. Or society has guided us towards considering much of it as apolitical when is not for the purpose of perpetuating the existing power structures (capitalism, patriarchy, and white supremacy).

Consumption is political

We live in a society dictated by capitalism, and it has infiltrated not only our markets but every aspect of our lives. We all know when you buy an apple from the store not all of it goes to the workers; it's putting some amount of money in capitalists' pockets and further accumulating wealth at the top of the hierarchy. We know the prices are only as low as they are due to the exploitation of workers all around the world working in horrible conditions for horrible pay. We know the company we buy from is organized like a totalitarian regime where all the decisions come from up high and serve to benefit those at the top. So why isn't buying an apple political?

Engaging in our market economy is both a necessity for our survival, and normalized through decades and decades of propaganda and reinforcement of the status quo. We become alienated to the effects of our actions as a defense measure because our daily complicity in various atrocities are simply too grand to carry on our shoulders. It becomes apolitical out of necessity. This has a side effect of making all challenges to the status quo (progressivism) appear far more controversial and political than just keeping things as they are.

With so many things becoming commodified, this effect becomes stronger with time. Our culture, love, attention have all been commodified. Everything being for sale means politics affects everything.

The Search For The Apolitical Video Game goes over how essentially everything is political, through the framework of searching for an "apolitical" video game. The arguments they make for video games trivially apply to all forms of media. If all media is political, so is the act of consuming it. Even news will always have a bias, as Objectivity doesn't exist.

r/NonPoliticalTwitter

This is a subreddit that claims to only allow non-political content. Naturally, this is a good case study to argue why the concept of non-political content doesn't exist. They have an interesting interpretation of politics, wherein content can even involve political figures, if the focus of the post isn't considered political. This leads to one of the top posts at the time of writing being about Jimmy Carter giving a speech in Japan. So its a post about a US president engaging in politics abroad, but the post focuses on how an interpreter handled a joke, so it's not political. There's naturally no discussion on why Carter was in Japan or putting this event in a broader context of the relationship between the US and Japan after WW2 and Carter's role in repairing it.

Even when they don't involve US presidents, nearly every post on that subreddit can be associated with politics. Complaining about subscription costs and how support agents can reduce the prices to keep you from leaving is apolitical, as is discussing how childrens cereal is so unhealthy ants disregard it as food. Apparently criticizing the lies told to us by our education system is apolitical, just like voicing distaste with how much advertising corporations spam. These are political issues, and they're only able to pass as apolitical by maintaining a lack of awareness on how politics shape society.

Inaction is political

There is no "apolitical" perspective, as that's really just the stance of maintaining the political status quo. As put by Angela Davis, "In a racist society it is not enough to be non-racist, we must be anti-racist." Essentially, politics affect all of us and everything is political, and if you believe politics don't effect you, that's probably because the current political and economic systems work in your favor.

How to radicalize a normie describes how communities can be overtaken by fascists exploiting the fact that statements that are deemed "apolitical" are the ones with consensus, coupled with the fact that progressive statements, by challenging the status quo, are not going to have consensus in communities without a political alignment.

Centrism has no merit

Adjacent to people seeking to avoid politics outright are those who hold the belief that our two parties are on polar extremes and hold the belief the correct position is going to be somewhere in the middle, taking aspects of both parties. This is fallacious because the center has no special value that makes it better than the extremes, a lot of the issues centrists want to pull from the different parties never needed to be politicized in the first place, and the two US parties are not on polar extremes anyways.

The center is just the midpoint between two points. That's it. Rejecting both sides doesn't make you intellectually or morally superior. The horseshoe theory was never a good theory to begin with, with the underlying political philosophies between the two sides being fundamentally opposed. I recommend "Blackshirts and Reds" by Michael Parenti if you'd like a better understanding of why the two ideologies are polar opposites, and how they clashed.

In practice these midpoints don't even make much sense to uphold. If the left says trans people should not be discriminated against, and the right says they shouldn't exist, where's the midpoint? We should discriminate against trans people but allow them to exist? Oh, how kind. In practice this is literally the stance liberals take, though: trans people can exist, but how dare you support Trans athletes in sports!

Today, centrism in America is not even talking about the midpoint between the rightist and leftist ideologies, but rather the Republicans and Democrats. These are arbitrary points dictated by the Overton Window that make the midpoint even more arbitrary. What is the midpoint between socialism and capitalism? The former is defined by private property not existing, the latter the opposite. Any midpoint is clearly still just capitalism, just with some regulations to temporarily stave off crises caused by capitalism's contradictions. The two US parties are both in defense of private ownership of the means of production, so the midpoint was never really going to be anywhere close to the left. This is why Bernie Sanders was called a "true" centrist because, by being further left than the Democrats, he actually was closer to whatever the actual midpoint between the far left and far right would be. Even then, the other arguments against centrism still apply.

Like political apathy, centrism is really just a bias towards the status quo, which I shall remind you is shaped by unjust power structures like capitalism, patriarchy, and white supremacy. All my arguments, both here and in my page against "No Politics" Rules, apply equally to centrists as they do the politically apathetic. The Angela Davis quote once again comes to mind: "In a racist society it is not enough to be non-racist, we must be anti-racist."

',20),w=JSON.parse('{"title":"Everything is Political","description":"","frontmatter":{"public":"true","slug":"everything-is-political","title":"Everything is Political","prev":false,"next":false},"headers":[],"relativePath":"garden/everything-is-political/index.md","filePath":"garden/everything-is-political/index.md"}'),u={name:"garden/everything-is-political/index.md"},b=Object.assign(u,{setup(d){const i=o();return(m,f)=>(l(),s("div",null,[h,e("p",null,[n("1100 words, ~6 minute read. "),e("span",{innerHTML:t(a)[`site/${t(i).page.value.relativePath}`]},null,8,c)]),p]))}});export{w as __pageData,b as default}; diff --git a/assets/garden_everything-is-political_index.md.CdBgMXxj.lean.js b/assets/garden_everything-is-political_index.md.rbSDwqZc.lean.js similarity index 92% rename from assets/garden_everything-is-political_index.md.CdBgMXxj.lean.js rename to assets/garden_everything-is-political_index.md.rbSDwqZc.lean.js index 3b6705a00..cb7098315 100644 --- a/assets/garden_everything-is-political_index.md.CdBgMXxj.lean.js +++ b/assets/garden_everything-is-political_index.md.rbSDwqZc.lean.js @@ -1 +1 @@ -import{d as a}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as s,Q as e,K as n,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Everything is Political",-1),c=["innerHTML"],p=r("",20),w=JSON.parse('{"title":"Everything is Political","description":"","frontmatter":{"public":"true","slug":"everything-is-political","title":"Everything is Political","prev":false,"next":false},"headers":[],"relativePath":"garden/everything-is-political/index.md","filePath":"garden/everything-is-political/index.md"}'),u={name:"garden/everything-is-political/index.md"},b=Object.assign(u,{setup(d){const i=o();return(m,f)=>(l(),s("div",null,[h,e("p",null,[n("1100 words, ~6 minute read. "),e("span",{innerHTML:t(a)[`site/${t(i).page.value.relativePath}`]},null,8,c)]),p]))}});export{w as __pageData,b as default}; +import{d as a}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as s,Q as e,K as n,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Everything is Political",-1),c=["innerHTML"],p=r("",20),w=JSON.parse('{"title":"Everything is Political","description":"","frontmatter":{"public":"true","slug":"everything-is-political","title":"Everything is Political","prev":false,"next":false},"headers":[],"relativePath":"garden/everything-is-political/index.md","filePath":"garden/everything-is-political/index.md"}'),u={name:"garden/everything-is-political/index.md"},b=Object.assign(u,{setup(d){const i=o();return(m,f)=>(l(),s("div",null,[h,e("p",null,[n("1100 words, ~6 minute read. "),e("span",{innerHTML:t(a)[`site/${t(i).page.value.relativePath}`]},null,8,c)]),p]))}});export{w as __pageData,b as default}; diff --git a/assets/garden_fedi-v2_index.md.Dk37-aPG.js b/assets/garden_fedi-v2_index.md.CThQv-zy.js similarity index 99% rename from assets/garden_fedi-v2_index.md.Dk37-aPG.js rename to assets/garden_fedi-v2_index.md.CThQv-zy.js index aa1f30121..804139659 100644 --- a/assets/garden_fedi-v2_index.md.Dk37-aPG.js +++ b/assets/garden_fedi-v2_index.md.CThQv-zy.js @@ -1 +1 @@ -import{d as o}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as s,Q as e,K as n,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Fedi v2",-1),d=["innerHTML"],c=r('
Referenced by:Chromatic LatticeDecentralized Social MediaDecentralizedDigital LocalityFilter BubblesIncremental Social/nowOrchardSocial MediaThe IndieWeb/Signature BlocksWeird

A placeholder name for a theoretical new federated network that is client-centric, in contrast to the server-centric Fediverse. Many of the ideas here will be implemented as described or similarly by people much smarter than me as part of Agentic Federation on Iroh, an initiative by the Weird developers.

Motivation

The current fediverse, while in theory fully Decentralized, in practice suffers many of the issues associated with centralization. This is primarily caused by the friction of having to pick a server and the non feasibility of individuals buying a domain and setting up a single user instance - both of these causes lead to a handful of large servers with the bulk of the users. You can see this in action by looking up the relative sizes of lemmy and mastodon instances. Single-user Mastodon Instance is a Bad Idea goes over the non feasibility of self hosting and how it contributes to a handful of servers having the majority of the users.

The promise of federation is the ability to interact with the whole network, while being able to fully choose and customize how you yourself interact with the network. In practice though, clients are severely limited to what they can do based on the server software. Of particular note, Lemmy and Mastodon show content in different formats (threads vs microblogs), and no clients allow changing how they're displayed, or respecting the format of the source of the content. Clients also are unable to change sorting algorithms or how downvotes are handled - those are all dependent on the server. A Plan for Social Media - Rethinking Federation similarly criticizes how much of the decisions are dependent on the server, which most people won't be able to or willing to self host.

The pick a server problem is such a problem because not only do you have to pick what server has moderation policies you align with, but that you're also linking your identity with that server. Smaller servers tend to be more focused or niche, which is unlikely to fully encompass any person's entire identity. Why would I confine myself to being thepaperpilot@writinglovers.com if I'm more than a writing lover? Additionally, I'm risking that the community at that instance won't grow away from things I want to associate with, such as fascism or crypto. My identity could end up being associated with things I drastically don't want it to be.

Nostr fixes the pick a server problem with a properly decentralized identity, however it's done so by associating itself with crypto and the alt right, and fixing that culture problem is more effort than it's worth. It'll be difficult to gain broad adoption as anyone using the platform will have to take care to explain how they're using nostr but aren't alt right.

ATProto by bluesky offers a version of federation built for a handful of large instances, but allowing smaller servers to be spun up that can implement custom sorting algorithms, views, etc. Your identity can be tied to a domain you own, if you have one. This fixes a couple of the problems where you're unable to change certain things dictated by the servers, but doesn't quite go far enough. Their PDS system is very similar to what we're going for, but it's still tied to signing up at (and then relying upon) specific servers.

NextGraph looks very similar to what we're trying to build. My only note is really that it gives a bit of a crypto vibe through decisions like calling identities "wallets" that I think may make it fall into the same problems nostr has, but conceptually its really similar to everything discussed here, which is great! It should be incredibly easy to interoperate, at the very least.

Decentralized Identity

The decentralized fediverse should have a fully decentralized identity, where it's completely attached to the client rather than any server(s). This means you don't have to pick a server, worry about your chosen server going down, or that your identity will become associated with an undesired community. It can properly allow you to engage in your variety of interests without having to associate your identity with just one.

By relying on signed messages, content (posts, profile information, etc.) is also not attached to any specific delivery system. Relay servers, a USB stick, or QR code could all work and still have the guarantees it was written by someone with the private key and has not been tampered with. It should be noted that none of the major social media platforms existing today can give verifiable proof a message was not tampered with.

Servers

Servers would act as mere relays, whose job it is is to store messages and send them to any other clients or servers that have requested to hear about any new messages. Some relays may also display these messages in a web interface, so that you can still share links to messages online. Because your identity isn't attached to any specific server, you could send your messages out to any servers you wish, and change that list as often as you'd like. It's extremely resilient to individual servers going down.

If you want a private network, say for a school or job, you could setup a relay server that requires some sort of password when sending them messages, and then have that server not federate with the rest of the fediverse.

Servers would give clients ways to subscribe to subsets of all received messages - e.g. all messages, all messages from a specific user, any replies to messages from a specific user, or "shallow" subscriptions to a message, meaning it'll send you only 1 level of replies to that message.

With a decentralized identity and the ability to switch servers seamlessly whenever you want, many of the benefits of self hosting a server are granted to everyone. This means there'll likely be fewer servers than the current fediverse has. There'll likely be enough to ensure redundancy, but beyond that I'd really only expect a couple large servers, similar to how bluesky intends AtProto to have, and perhaps smaller instances by institutions that want to provide storage for the people within that institution. Fortunately, it also means the disadvantages of only having 1 or a small number of servers also go away. We only need enough instances for redundancy, but beyond that we don't need to worry about being locked into a server or your server having rules you disagree with or anything. You'll always have your data, and can just send it to another server whenever you'd like. These fewer but larger servers will be useful for discoverability with less traffic between all the servers.

Content

The protocol should be fairly content agnostic, and allow arbitrary metadata on messages that can be used by the community to come up with their own new forms of content to transmit over the protocol. For example, perhaps there's a body field that could include arbitrary text or binary data, and for binary data another field could clarify if its audio, video, an image, or something else.

The signature of the message acts as the de facto ID of that message, for replying purposes. Edits and reactions would be handled by "replying" to a message with a metadata flag indicating what the message actually represents. Edit messages should typically be ignored if they're not from the same author as the original message. We should assume some servers will always make an edit history fully public. Reactions should just be replies without any actual body, and a tag for what the reaction is - either binary image data or a code representing an emoji, like "+1" or "laughing". Upvotes and downvotes could be implemented via reactions.

Edit replies could be sent by people other than the original poster as well. Perhaps some clients would trust edits from a list of identities, but the original poster could also reply to an edit message with an "accepted" message as a form of officially accepting/endorsing that edit suggestion. Clients could also potentially include a list of "proposed edits" that haven't been accepted.

Groups/communities could also be specially flagged messages, effectively allowing for subreddit-style content. Posting to the community is just replying to the message. Subscribing to that community is just subscribing to that message. The original message creator can send edits to update stuff like the description of the community. Perhaps they can also send a message detailing other identities to trust for editing or moderating the community.

A bot could fairly easily be setup to make IndieWeb posts and web mentions use this protocol. Indeed, this protocol is very POSSE-friendly because you could have your original content on the website, and the messages can be spread across the network while allowing clients to verify it was untampered with and definitely came from that website. I plan on writing a proposal for IndieWeb posts to include The IndieWeb/Signature Blocks to enable this. Within this framework, Fedi v2 would not just be a other social media silo. It would be the source of truth, fully controlled by the author. Even if the author cross posts to other social media (silos), we'd effectively still be the original copy.

Decentralized Moderation

Success

I believe the main benefits of this new fediverse are mostly going to apply to the techy power users who will appreciate the increased control over their identity and browsing experience. As far as the general public goes, I think the main benefit will be verified authorship and guaranteeing lack of tampering. Specifically, I think this will appeal to notable figures who have to be wary of concerns like that. Reddit and Twitter could edit your content or stifle it in the algorithm, or any other sort of malicious actions. So I think success of this platform will mostly come from seeing notable figures switching to it, and treating is as the source of truth (even if they cross post it to other platforms for increased outreach). Ideally, they even host their messages on their own website.

Component Definitions

The agentic fediverse is currently being designed such that messages are entities in a Entity-Component relationship. Component schemas can then be formally defined and then implemented in clients, without the need of a centralized authority releasing formal spec bumps. In theory anyone could propose a new schema.

Here's some initial ideas for components I currently plan on proposing and perhaps even implementing:

  • Community (placeholder name): Marks that replies to this message should be displayed like a collection of threads, reddit-style.
  • Delete: Marks that this message is a deletion request to the message its a reply to.
    • Can be used to delete specific components in the parent message.
  • Edit: Marks that this message is an edit request to the message its a reply to.
    • Can be used to edit specific components in the parent message.
  • Accept: Marks that any requests in the message this message is a reply to were accepted.
    • Takes an optional schema property to identify which specific request component of the parent message was accepted.
  • Reaction: Marks that this message is a reaction to the message its a reply to.
  • Ascii: Describes a text component to be rendered.
  • Unicode: Describes a text component to be rendered.
  • Image: Describes an image component to be rendered. (Or perhaps specific file formats should have their own schemas)
  • Audio: Describes an audio component to be rendered. (Or perhaps specific file formats should have their own schemas)
  • Video: Describes a video component to be rendered. (Or perhaps specific file formats should have their own schemas)
  • Topics: Describes a list of topics/tags this message is relevant to, for use in client searching and filtering.
  • Editors: Describes a list of identities who have the power to edit this message, or accept edit requests to this message.
  • Deleters: Describes a list of identities who have the power to delete this message, or accept deletion requests to this message.
  • No Discovery: Marks that this message should not be included in any global feeds or search results. Servers should only send it to servers and clients that subscribe to messages like this one.
  • Timestamp Requested: Marks that this message would like to receive a response from a trusted server (optionally defined in the component data) once it is delivered. May also include a schema ID that represents what the timestamp represents. Defaults to referring to the published date.
  • Calendar Event: Describes a calendar event.
  • RSVP: Marks that you [are, might be, or aren't] participating in whatever a linked entity is describing.

Chatting

The agentic fediverse could theoretically also implement chat rooms, bringing advantages (like divorcing identity from servers) that current decentralized chat protocols like matrix don't offer.

Here are some of the components that could be used to represent a chat room:

  • Chat room: Marks that replies to this message should be shown as messages in a chat room.
  • Bridge: Marks that this identity is a bridge for an account on another service. Implies that the verification of authorship may not be preserved.

Games

The agentic fediverse could support sharing games using a Game component that includes a url or raw html required to play a game. In theory they could even support "cloud saves" by signing a message of their save data that only they can decrypt and sending it as a reply to the game message. Clients could handle displaying the game alongside the usual filtering and sorting features.

I'd also be excited in seeing a sort of MMO style game on the agentic fediverse. So you see other players and there's a shared game state, calculated on the client based on the actions recorded by the various different players. And since the rules would have to be defined by the components, people could create their own copies of the world (e.g. to play with a friend group or solo), or even make their own mods of the game. I'd like to look into that. I'll perhaps rethink Chromatic Lattice to work on such a framework, although it may be too complicated for this idea.

Having the game state be calculatable by the client like that would also allow trophies and achievements to work verifiably. People could probably still write software to copy someone else's events at the right times and effectively replicate their save, but I think that won't happen commonly enough to matter.

Permissions

Instead of having various different licenses like CC0, MIT, etc., just make each permission discrete. For example, you can have a DoNotTrainOn component that marks that using an entity for training AI models is not allowed.

This is different from the willow permissions system which determines who can read or write to specific entities/paths. This is for telling someone who has read access to your post what they're allowed to use it for.

There should be a component that makes permissions explicit rather than implicit. E.g. assume you don't have the right to do anything unless explicitly stated.

Local identity and contact management

If I have multiple apps that use the agentic fediverse (e.g. one for reddit like content, one for Twitter, discord, Google drive, etc.), I'd like to easily have them all use the same identity(s), as well as a shared contact list (so I know the person I saw do something on one app is the same as the person that did something on another app).

To that end, there should be an app/program that manages your identities and contacts on that device. It sets up your initial identity, any cloud backups, etc., and the other apps talk to it as needed. That could be sending it individual messages to sign or asking for a key that can be used to do limited functionality.

Contacts could be signed such that they're only readable by us, and then sent over the network so I can have multiple devices that keep their contact list synced between them

An identity management app could also work as a link handler for the leaf protocol. It could take a schema ID as another path component, which then describes the purpose of the URI and the expected remaining data in the URI. The identity management app can then pass the message along to any app that has specified it knows how to handle that schema.

Sustainability

Servers are expensive, especially as they get popular. Most current fediverse instances are free and funded by donations. Things like ads or paying for an account are difficult to do due to the nature of federation. This is a pretty major problem because if a server becomes too expensive to host, it will shut down, along with all the accounts associated with it. Fedi v2 makes individual servers going down not be an issue anymore, since identities aren't attached to them. However, it's an issue if all the instances go down, and if there's no way to pay for them still, why would any instance stay up?

Since instance nodes do not have to do filtering, sorting, or really any other processing, but rather just serving the events and sending out notifications to clients, the cost will be cheaper than the current fediverse. It's really just a file server, which is cheap. For example, idrive charges $40 per tb per year, which is enough for a LOT of content. So I expect some instance nodes to have fairly generous free tiers that will suffice for a lot of users. Idrive also doesn't have egress charges, so the cost only scales with how much content is being published, not downloaded.

For power users, instance nodes could accept payments to store data above the free quota. This would likely most often happen for people wishing to upload high resolution images or videos. A user could also switch nodes after filling a quota on one node - you don't have to delete your content on the old instance. You could also do this to backup your content on multiple nodes (although you should also keep a local copy of all your content).

I assume this aspect of Fedi v2 will be the most controversial - people really like free services, and are expecting it. Knowing they might eventually need to pay to post more will perhaps require a cultural shift. I think it's worth it to not have ads or tracking, and in general we should be supporting sustainable services.

What about Incremental Social?

I think Incremental Social can operate similarly to weird.one, hosting an iroh node and storing events for the agentic fediverse for users of the site. We'll generate and manage a keypair for the user, with the possibility of the user migrating their identity.

I suspect the way the identity management app will work to support sites like weird.one and incremental.social is by passing the request for a delegate key to incremental.social, which will then show the consent screen before passing the key back to the app which sends it to the actual fediverse app.

',56),b=JSON.parse('{"title":"Fedi v2","description":"","frontmatter":{"alias":"Agentic Fediverse","public":"true","slug":"fedi-v2","title":"Fedi v2","prev":false,"next":false},"headers":[],"relativePath":"garden/fedi-v2/index.md","filePath":"garden/fedi-v2/index.md"}'),u={name:"garden/fedi-v2/index.md"},w=Object.assign(u,{setup(p){const a=i();return(m,g)=>(l(),s("div",null,[h,e("p",null,[n("3033 words, ~17 minute read. "),e("span",{innerHTML:t(o)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),c]))}});export{b as __pageData,w as default}; +import{d as o}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as s,Q as e,K as n,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Fedi v2",-1),d=["innerHTML"],c=r('
Referenced by:Chromatic LatticeDecentralized Social MediaDecentralizedDigital LocalityFilter BubblesIncremental Social/nowOrchardSocial MediaThe IndieWeb/Signature BlocksWeird

A placeholder name for a theoretical new federated network that is client-centric, in contrast to the server-centric Fediverse. Many of the ideas here will be implemented as described or similarly by people much smarter than me as part of Agentic Federation on Iroh, an initiative by the Weird developers.

Motivation

The current fediverse, while in theory fully Decentralized, in practice suffers many of the issues associated with centralization. This is primarily caused by the friction of having to pick a server and the non feasibility of individuals buying a domain and setting up a single user instance - both of these causes lead to a handful of large servers with the bulk of the users. You can see this in action by looking up the relative sizes of lemmy and mastodon instances. Single-user Mastodon Instance is a Bad Idea goes over the non feasibility of self hosting and how it contributes to a handful of servers having the majority of the users.

The promise of federation is the ability to interact with the whole network, while being able to fully choose and customize how you yourself interact with the network. In practice though, clients are severely limited to what they can do based on the server software. Of particular note, Lemmy and Mastodon show content in different formats (threads vs microblogs), and no clients allow changing how they're displayed, or respecting the format of the source of the content. Clients also are unable to change sorting algorithms or how downvotes are handled - those are all dependent on the server. A Plan for Social Media - Rethinking Federation similarly criticizes how much of the decisions are dependent on the server, which most people won't be able to or willing to self host.

The pick a server problem is such a problem because not only do you have to pick what server has moderation policies you align with, but that you're also linking your identity with that server. Smaller servers tend to be more focused or niche, which is unlikely to fully encompass any person's entire identity. Why would I confine myself to being thepaperpilot@writinglovers.com if I'm more than a writing lover? Additionally, I'm risking that the community at that instance won't grow away from things I want to associate with, such as fascism or crypto. My identity could end up being associated with things I drastically don't want it to be.

Nostr fixes the pick a server problem with a properly decentralized identity, however it's done so by associating itself with crypto and the alt right, and fixing that culture problem is more effort than it's worth. It'll be difficult to gain broad adoption as anyone using the platform will have to take care to explain how they're using nostr but aren't alt right.

ATProto by bluesky offers a version of federation built for a handful of large instances, but allowing smaller servers to be spun up that can implement custom sorting algorithms, views, etc. Your identity can be tied to a domain you own, if you have one. This fixes a couple of the problems where you're unable to change certain things dictated by the servers, but doesn't quite go far enough. Their PDS system is very similar to what we're going for, but it's still tied to signing up at (and then relying upon) specific servers.

NextGraph looks very similar to what we're trying to build. My only note is really that it gives a bit of a crypto vibe through decisions like calling identities "wallets" that I think may make it fall into the same problems nostr has, but conceptually its really similar to everything discussed here, which is great! It should be incredibly easy to interoperate, at the very least.

Decentralized Identity

The decentralized fediverse should have a fully decentralized identity, where it's completely attached to the client rather than any server(s). This means you don't have to pick a server, worry about your chosen server going down, or that your identity will become associated with an undesired community. It can properly allow you to engage in your variety of interests without having to associate your identity with just one.

By relying on signed messages, content (posts, profile information, etc.) is also not attached to any specific delivery system. Relay servers, a USB stick, or QR code could all work and still have the guarantees it was written by someone with the private key and has not been tampered with. It should be noted that none of the major social media platforms existing today can give verifiable proof a message was not tampered with.

Servers

Servers would act as mere relays, whose job it is is to store messages and send them to any other clients or servers that have requested to hear about any new messages. Some relays may also display these messages in a web interface, so that you can still share links to messages online. Because your identity isn't attached to any specific server, you could send your messages out to any servers you wish, and change that list as often as you'd like. It's extremely resilient to individual servers going down.

If you want a private network, say for a school or job, you could setup a relay server that requires some sort of password when sending them messages, and then have that server not federate with the rest of the fediverse.

Servers would give clients ways to subscribe to subsets of all received messages - e.g. all messages, all messages from a specific user, any replies to messages from a specific user, or "shallow" subscriptions to a message, meaning it'll send you only 1 level of replies to that message.

With a decentralized identity and the ability to switch servers seamlessly whenever you want, many of the benefits of self hosting a server are granted to everyone. This means there'll likely be fewer servers than the current fediverse has. There'll likely be enough to ensure redundancy, but beyond that I'd really only expect a couple large servers, similar to how bluesky intends AtProto to have, and perhaps smaller instances by institutions that want to provide storage for the people within that institution. Fortunately, it also means the disadvantages of only having 1 or a small number of servers also go away. We only need enough instances for redundancy, but beyond that we don't need to worry about being locked into a server or your server having rules you disagree with or anything. You'll always have your data, and can just send it to another server whenever you'd like. These fewer but larger servers will be useful for discoverability with less traffic between all the servers.

Content

The protocol should be fairly content agnostic, and allow arbitrary metadata on messages that can be used by the community to come up with their own new forms of content to transmit over the protocol. For example, perhaps there's a body field that could include arbitrary text or binary data, and for binary data another field could clarify if its audio, video, an image, or something else.

The signature of the message acts as the de facto ID of that message, for replying purposes. Edits and reactions would be handled by "replying" to a message with a metadata flag indicating what the message actually represents. Edit messages should typically be ignored if they're not from the same author as the original message. We should assume some servers will always make an edit history fully public. Reactions should just be replies without any actual body, and a tag for what the reaction is - either binary image data or a code representing an emoji, like "+1" or "laughing". Upvotes and downvotes could be implemented via reactions.

Edit replies could be sent by people other than the original poster as well. Perhaps some clients would trust edits from a list of identities, but the original poster could also reply to an edit message with an "accepted" message as a form of officially accepting/endorsing that edit suggestion. Clients could also potentially include a list of "proposed edits" that haven't been accepted.

Groups/communities could also be specially flagged messages, effectively allowing for subreddit-style content. Posting to the community is just replying to the message. Subscribing to that community is just subscribing to that message. The original message creator can send edits to update stuff like the description of the community. Perhaps they can also send a message detailing other identities to trust for editing or moderating the community.

A bot could fairly easily be setup to make IndieWeb posts and web mentions use this protocol. Indeed, this protocol is very POSSE-friendly because you could have your original content on the website, and the messages can be spread across the network while allowing clients to verify it was untampered with and definitely came from that website. I plan on writing a proposal for IndieWeb posts to include The IndieWeb/Signature Blocks to enable this. Within this framework, Fedi v2 would not just be a other social media silo. It would be the source of truth, fully controlled by the author. Even if the author cross posts to other social media (silos), we'd effectively still be the original copy.

Decentralized Moderation

Success

I believe the main benefits of this new fediverse are mostly going to apply to the techy power users who will appreciate the increased control over their identity and browsing experience. As far as the general public goes, I think the main benefit will be verified authorship and guaranteeing lack of tampering. Specifically, I think this will appeal to notable figures who have to be wary of concerns like that. Reddit and Twitter could edit your content or stifle it in the algorithm, or any other sort of malicious actions. So I think success of this platform will mostly come from seeing notable figures switching to it, and treating is as the source of truth (even if they cross post it to other platforms for increased outreach). Ideally, they even host their messages on their own website.

Component Definitions

The agentic fediverse is currently being designed such that messages are entities in a Entity-Component relationship. Component schemas can then be formally defined and then implemented in clients, without the need of a centralized authority releasing formal spec bumps. In theory anyone could propose a new schema.

Here's some initial ideas for components I currently plan on proposing and perhaps even implementing:

  • Community (placeholder name): Marks that replies to this message should be displayed like a collection of threads, reddit-style.
  • Delete: Marks that this message is a deletion request to the message its a reply to.
    • Can be used to delete specific components in the parent message.
  • Edit: Marks that this message is an edit request to the message its a reply to.
    • Can be used to edit specific components in the parent message.
  • Accept: Marks that any requests in the message this message is a reply to were accepted.
    • Takes an optional schema property to identify which specific request component of the parent message was accepted.
  • Reaction: Marks that this message is a reaction to the message its a reply to.
  • Ascii: Describes a text component to be rendered.
  • Unicode: Describes a text component to be rendered.
  • Image: Describes an image component to be rendered. (Or perhaps specific file formats should have their own schemas)
  • Audio: Describes an audio component to be rendered. (Or perhaps specific file formats should have their own schemas)
  • Video: Describes a video component to be rendered. (Or perhaps specific file formats should have their own schemas)
  • Topics: Describes a list of topics/tags this message is relevant to, for use in client searching and filtering.
  • Editors: Describes a list of identities who have the power to edit this message, or accept edit requests to this message.
  • Deleters: Describes a list of identities who have the power to delete this message, or accept deletion requests to this message.
  • No Discovery: Marks that this message should not be included in any global feeds or search results. Servers should only send it to servers and clients that subscribe to messages like this one.
  • Timestamp Requested: Marks that this message would like to receive a response from a trusted server (optionally defined in the component data) once it is delivered. May also include a schema ID that represents what the timestamp represents. Defaults to referring to the published date.
  • Calendar Event: Describes a calendar event.
  • RSVP: Marks that you [are, might be, or aren't] participating in whatever a linked entity is describing.

Chatting

The agentic fediverse could theoretically also implement chat rooms, bringing advantages (like divorcing identity from servers) that current decentralized chat protocols like matrix don't offer.

Here are some of the components that could be used to represent a chat room:

  • Chat room: Marks that replies to this message should be shown as messages in a chat room.
  • Bridge: Marks that this identity is a bridge for an account on another service. Implies that the verification of authorship may not be preserved.

Games

The agentic fediverse could support sharing games using a Game component that includes a url or raw html required to play a game. In theory they could even support "cloud saves" by signing a message of their save data that only they can decrypt and sending it as a reply to the game message. Clients could handle displaying the game alongside the usual filtering and sorting features.

I'd also be excited in seeing a sort of MMO style game on the agentic fediverse. So you see other players and there's a shared game state, calculated on the client based on the actions recorded by the various different players. And since the rules would have to be defined by the components, people could create their own copies of the world (e.g. to play with a friend group or solo), or even make their own mods of the game. I'd like to look into that. I'll perhaps rethink Chromatic Lattice to work on such a framework, although it may be too complicated for this idea.

Having the game state be calculatable by the client like that would also allow trophies and achievements to work verifiably. People could probably still write software to copy someone else's events at the right times and effectively replicate their save, but I think that won't happen commonly enough to matter.

Permissions

Instead of having various different licenses like CC0, MIT, etc., just make each permission discrete. For example, you can have a DoNotTrainOn component that marks that using an entity for training AI models is not allowed.

This is different from the willow permissions system which determines who can read or write to specific entities/paths. This is for telling someone who has read access to your post what they're allowed to use it for.

There should be a component that makes permissions explicit rather than implicit. E.g. assume you don't have the right to do anything unless explicitly stated.

Local identity and contact management

If I have multiple apps that use the agentic fediverse (e.g. one for reddit like content, one for Twitter, discord, Google drive, etc.), I'd like to easily have them all use the same identity(s), as well as a shared contact list (so I know the person I saw do something on one app is the same as the person that did something on another app).

To that end, there should be an app/program that manages your identities and contacts on that device. It sets up your initial identity, any cloud backups, etc., and the other apps talk to it as needed. That could be sending it individual messages to sign or asking for a key that can be used to do limited functionality.

Contacts could be signed such that they're only readable by us, and then sent over the network so I can have multiple devices that keep their contact list synced between them

An identity management app could also work as a link handler for the leaf protocol. It could take a schema ID as another path component, which then describes the purpose of the URI and the expected remaining data in the URI. The identity management app can then pass the message along to any app that has specified it knows how to handle that schema.

Sustainability

Servers are expensive, especially as they get popular. Most current fediverse instances are free and funded by donations. Things like ads or paying for an account are difficult to do due to the nature of federation. This is a pretty major problem because if a server becomes too expensive to host, it will shut down, along with all the accounts associated with it. Fedi v2 makes individual servers going down not be an issue anymore, since identities aren't attached to them. However, it's an issue if all the instances go down, and if there's no way to pay for them still, why would any instance stay up?

Since instance nodes do not have to do filtering, sorting, or really any other processing, but rather just serving the events and sending out notifications to clients, the cost will be cheaper than the current fediverse. It's really just a file server, which is cheap. For example, idrive charges $40 per tb per year, which is enough for a LOT of content. So I expect some instance nodes to have fairly generous free tiers that will suffice for a lot of users. Idrive also doesn't have egress charges, so the cost only scales with how much content is being published, not downloaded.

For power users, instance nodes could accept payments to store data above the free quota. This would likely most often happen for people wishing to upload high resolution images or videos. A user could also switch nodes after filling a quota on one node - you don't have to delete your content on the old instance. You could also do this to backup your content on multiple nodes (although you should also keep a local copy of all your content).

I assume this aspect of Fedi v2 will be the most controversial - people really like free services, and are expecting it. Knowing they might eventually need to pay to post more will perhaps require a cultural shift. I think it's worth it to not have ads or tracking, and in general we should be supporting sustainable services.

What about Incremental Social?

I think Incremental Social can operate similarly to weird.one, hosting an iroh node and storing events for the agentic fediverse for users of the site. We'll generate and manage a keypair for the user, with the possibility of the user migrating their identity.

I suspect the way the identity management app will work to support sites like weird.one and incremental.social is by passing the request for a delegate key to incremental.social, which will then show the consent screen before passing the key back to the app which sends it to the actual fediverse app.

',56),b=JSON.parse('{"title":"Fedi v2","description":"","frontmatter":{"alias":"Agentic Fediverse","public":"true","slug":"fedi-v2","title":"Fedi v2","prev":false,"next":false},"headers":[],"relativePath":"garden/fedi-v2/index.md","filePath":"garden/fedi-v2/index.md"}'),u={name:"garden/fedi-v2/index.md"},w=Object.assign(u,{setup(p){const a=i();return(m,g)=>(l(),s("div",null,[h,e("p",null,[n("3033 words, ~17 minute read. "),e("span",{innerHTML:t(o)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),c]))}});export{b as __pageData,w as default}; diff --git a/assets/garden_fedi-v2_index.md.Dk37-aPG.lean.js b/assets/garden_fedi-v2_index.md.CThQv-zy.lean.js similarity index 91% rename from assets/garden_fedi-v2_index.md.Dk37-aPG.lean.js rename to assets/garden_fedi-v2_index.md.CThQv-zy.lean.js index b78564c01..05a1d8ad9 100644 --- a/assets/garden_fedi-v2_index.md.Dk37-aPG.lean.js +++ b/assets/garden_fedi-v2_index.md.CThQv-zy.lean.js @@ -1 +1 @@ -import{d as o}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as s,Q as e,K as n,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Fedi v2",-1),d=["innerHTML"],c=r("",56),b=JSON.parse('{"title":"Fedi v2","description":"","frontmatter":{"alias":"Agentic Fediverse","public":"true","slug":"fedi-v2","title":"Fedi v2","prev":false,"next":false},"headers":[],"relativePath":"garden/fedi-v2/index.md","filePath":"garden/fedi-v2/index.md"}'),u={name:"garden/fedi-v2/index.md"},w=Object.assign(u,{setup(p){const a=i();return(m,g)=>(l(),s("div",null,[h,e("p",null,[n("3033 words, ~17 minute read. "),e("span",{innerHTML:t(o)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),c]))}});export{b as __pageData,w as default}; +import{d as o}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as s,Q as e,K as n,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Fedi v2",-1),d=["innerHTML"],c=r("",56),b=JSON.parse('{"title":"Fedi v2","description":"","frontmatter":{"alias":"Agentic Fediverse","public":"true","slug":"fedi-v2","title":"Fedi v2","prev":false,"next":false},"headers":[],"relativePath":"garden/fedi-v2/index.md","filePath":"garden/fedi-v2/index.md"}'),u={name:"garden/fedi-v2/index.md"},w=Object.assign(u,{setup(p){const a=i();return(m,g)=>(l(),s("div",null,[h,e("p",null,[n("3033 words, ~17 minute read. "),e("span",{innerHTML:t(o)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),c]))}});export{b as __pageData,w as default}; diff --git a/assets/garden_fediverse_index.md.mR-c57ag.js b/assets/garden_fediverse_index.md.DdsbJhRP.js similarity index 96% rename from assets/garden_fediverse_index.md.mR-c57ag.js rename to assets/garden_fediverse_index.md.DdsbJhRP.js index 30ba0b306..3b9c35f02 100644 --- a/assets/garden_fediverse_index.md.mR-c57ag.js +++ b/assets/garden_fediverse_index.md.DdsbJhRP.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as t,Q as e,K as n,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Fediverse",-1),c=["innerHTML"],m=s('
Referenced by:ATProtoDecentralized Social MediaDecentralizedFedi v2Incremental SocialMbinNostrSocial MediaThe Small WebViralityWeird

A collection of Social Media websites that can all talk to each other by virtue of a shared protocol.

Implementations:

',5),x=JSON.parse('{"title":"Fediverse","description":"","frontmatter":{"alias":"Federated Social Media","public":"true","slug":"fediverse","title":"Fediverse","prev":false,"next":false},"headers":[],"relativePath":"garden/fediverse/index.md","filePath":"garden/fediverse/index.md"}'),f={name:"garden/fediverse/index.md"},v=Object.assign(f,{setup(_){const d=i();return(h,p)=>(l(),t("div",null,[o,e("p",null,[n("22 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(d).page.value.relativePath}`]},null,8,c)]),m]))}});export{x as __pageData,v as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as t,Q as e,K as n,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Fediverse",-1),c=["innerHTML"],m=s('
Referenced by:ATProtoDecentralized Social MediaDecentralizedFedi v2Incremental SocialMbinNostrSocial MediaThe Small WebViralityWeird

A collection of Social Media websites that can all talk to each other by virtue of a shared protocol.

Implementations:

',5),x=JSON.parse('{"title":"Fediverse","description":"","frontmatter":{"alias":"Federated Social Media","public":"true","slug":"fediverse","title":"Fediverse","prev":false,"next":false},"headers":[],"relativePath":"garden/fediverse/index.md","filePath":"garden/fediverse/index.md"}'),f={name:"garden/fediverse/index.md"},v=Object.assign(f,{setup(_){const d=i();return(h,p)=>(l(),t("div",null,[o,e("p",null,[n("22 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(d).page.value.relativePath}`]},null,8,c)]),m]))}});export{x as __pageData,v as default}; diff --git a/assets/garden_fediverse_index.md.mR-c57ag.lean.js b/assets/garden_fediverse_index.md.DdsbJhRP.lean.js similarity index 91% rename from assets/garden_fediverse_index.md.mR-c57ag.lean.js rename to assets/garden_fediverse_index.md.DdsbJhRP.lean.js index 21d4c4459..505b5df4f 100644 --- a/assets/garden_fediverse_index.md.mR-c57ag.lean.js +++ b/assets/garden_fediverse_index.md.DdsbJhRP.lean.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as t,Q as e,K as n,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Fediverse",-1),c=["innerHTML"],m=s("",5),x=JSON.parse('{"title":"Fediverse","description":"","frontmatter":{"alias":"Federated Social Media","public":"true","slug":"fediverse","title":"Fediverse","prev":false,"next":false},"headers":[],"relativePath":"garden/fediverse/index.md","filePath":"garden/fediverse/index.md"}'),f={name:"garden/fediverse/index.md"},v=Object.assign(f,{setup(_){const d=i();return(h,p)=>(l(),t("div",null,[o,e("p",null,[n("22 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(d).page.value.relativePath}`]},null,8,c)]),m]))}});export{x as __pageData,v as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as t,Q as e,K as n,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Fediverse",-1),c=["innerHTML"],m=s("",5),x=JSON.parse('{"title":"Fediverse","description":"","frontmatter":{"alias":"Federated Social Media","public":"true","slug":"fediverse","title":"Fediverse","prev":false,"next":false},"headers":[],"relativePath":"garden/fediverse/index.md","filePath":"garden/fediverse/index.md"}'),f={name:"garden/fediverse/index.md"},v=Object.assign(f,{setup(_){const d=i();return(h,p)=>(l(),t("div",null,[o,e("p",null,[n("22 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(d).page.value.relativePath}`]},null,8,c)]),m]))}});export{x as __pageData,v as default}; diff --git a/assets/garden_filter-bubbles_index.md.-FC6NYD-.js b/assets/garden_filter-bubbles_index.md.qLDBKf98.js similarity index 99% rename from assets/garden_filter-bubbles_index.md.-FC6NYD-.js rename to assets/garden_filter-bubbles_index.md.qLDBKf98.js index fad7abd37..ca45d7784 100644 --- a/assets/garden_filter-bubbles_index.md.-FC6NYD-.js +++ b/assets/garden_filter-bubbles_index.md.qLDBKf98.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as r,Q as e,K as s,u as t,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Filter Bubbles",-1),c=["innerHTML"],d=n('
Referenced by:Digital LocalityObjectivity

Filter bubbles refer to how users may be intellectually isolated as a result of Social Media with algorithmic feeds, coupled with things like personalized search engine results and other services catering to someone's existing preferences and world views.

Are you in a filter bubble?

Absolutely, and without a doubt. Filter bubbles fractal inside each other, and most of them are entirely innocuous - they're not the scary boogeyman they've been portrayed as. If your search results are primarily English - you may be in a filter bubble. If the news you watch covers domestic issues within your country more than domestic issues in other countries - you may be in a filter bubble. If the local news you watch covers the weather in your local area but not in areas halfway across the globe - you may be in a filter bubble. These are not significantly contributing to the "intellectual isolation" filter bubbles are said to create, and no one is arguing we must be equally aware of the local weather across the world.

So yes, you're in a filter bubble - likely many, even. But that's not the right question to be asking; We must delve deeper into filter bubbles' causes and manifestations to determine what their negative aspects are and ultimately how to fix them.

Filter bubbles in search engines

The author of The Filter Bubble describes what is supposed to be a chilling story of a search for BP giving results on investment opportunities to one person, and news about the oil spill disaster to another. They posit this is indicative of a problem, but I question that the personalized search results did anything wrong here. Searching BP just by itself is a "neutral" search, and so I think its fine for it to have shown results based on what its learned that user usually looks companies up for. The implication is that the former is an individual who regularly searches companies to see their current investment opportunities, and got what they wanted. If this person were to suddenly want to, say, write a report on BP's history or ecological impact, they'd naturally search for something more specific than just "BP", and certainly find the results they're looking for. And of course, there's layers to this - Google is also figuring out what search results the average person usually wants when searching a given term, and ranking those higher. So the more people search for BP to get info on the disaster, the more prominent that disaster will be.

The problems stem from the various biases we all bring with us when researching anything, whether we're in a filter bubble or not. In this regard, filter bubbles are just automated applications of our own biases. For example, if you're researching the impact of the BP ecological disaster, your pre-conceived notions over its impact - and perhaps your personal financial interests - will dictate which sources you read at all, or ultimately decide to reference or ignore when discussing the issue with others. And to be clear, all sources will have a bias. There is no such thing as Objectivity, and even seemingly "neutral" outlets are implicitly defending the status quo of society.

I think most of you may relate to this, because we're all guilty of it, myself included. I've certainly shared news articles based on the headline, and perhaps even spend a bit too much time writing and not enough reading. Research papers in particular are incredibly dry and most people will only read articles about the paper, which may not be accurate, or perhaps only read the abstract, which may not be thorough. I'm keenly aware when citing a source that its unlikely someone will actually follow that link, to the point where it almost feels futile. Perhaps even now you're only skimming this page? Taken together, it seems an article existing with a given headline is more important than any arguments held within it.

Filter bubbles in social media

The more insidious issue of filter bubbles is when it applies passively, such as when you're on social media and simply don't see anything about an important topic, say the BP oil spill. But actually, part of the issue here isn't just not seeing the post, as even if someone sees posts about the event, they may be tainted with biases towards their existing world view, and the reader will just accept that interpretation at face value. After all, most users are not going to see a headline and start doing independent research to verify the claims held within the article. Hell, most won't even go as far as reading the article itself - as has been studied many times, sometimes in quite amusing widely shared but fake "prank" articles.

Even if you click a link, you may just skim the results. This is a problem because people are not reading articles to actually learn from them, but rather to confirm their pre-existing opinions on the topic. With that reassurance in hand, they'll share the articles and feel more confident they actually understand the topic.

A lot of the articles even available to share on social media are being crafted especially to be sharable using clickbait, caring more for covering topics profitably rather than ethically. AI slop has significantly compounded this issue by being able to mass produce articles that wholly lack meaningful insight, and is now a major problem for both search engines and social media platforms.

All the biases described above contribute to an especially problematic aspect of filter bubbles: the spreading of misinformation. If people are unwilling to verify provocative but ultimately wrong claims they read in a headline, then how do we fix that? There are different approaches people have suggested: algorithmic suppression by a independent organization tasked with verifying articles' legitimacy like Facebook, relying on community-driven notes like Twitter, or just trying to shift the culture to engage with social media more productively/healthily.

Are safe spaces filter bubbles?

The internet is a dangerous place, especially for members of marginalized groups. There are a lot of -phobes in the world, and the internet gives them a platform to harass far more widespread than before. It takes concerted effort to keep them out of communities, as described by Innuendo Studios' How to radicalize a normie. I think we should all be in agreement that it is entirely fine for people to want to filter out this kind of hateful content. So safe spaces are filter bubbles, but also are good and important things to have access to.

I bring this up to really drive home that filter bubbles are not intrinsically good or bad. They happen innocuously and are even beneficial for filtering out certain kinds of content. It's important any solution to the issues with filter bubbles focuses doesn't involve exposing people to, say, those who'd like to see them dead.

The line doesn't have to be at hateful content though. There's any number of content someone may want to filter out - gore, SA, or other PTSD triggers. Ultimately the line is subjective, and where the line is shouldn't be restricted or imposed. Empathy is the key here, and the same way a trans person shouldn't be encouraged to interact with transphobes, no one should be encouraged to engage in any social interactions they deem uncomfortable, even if others don't think it's uncomfortable.

Filtering politics

In the previous section I proposed that allowing people to decide what they want to see should is important. Most people can, I imagine, agree with that, barring one notable and often contested exception: politics. Our liberal democracy insists that universal political engagement is required for it to function properly. While I agree politics are critically important, politics should not be an exception that people "must" be subjected to regardless of their consent.

A lot of political topics are deeply personal and emotionally exhausting to engage with, particularly for those marginalized under the current power structures. For example, trans rights are an extremely important political issue, but demanding that trans people continually defend their very existence against reactionary attacks amounts to a form of re-traumatization. People not being exposed to these kinds of upsetting things is not a problem to be solved, and democracy can survive while allowing people to filter out political topics or perspectives they don't want to see. You do not need to tolerate the intolerant (as argued by Karl Popper, who coined the term "paradox of tolerance").

Admittedly, as a Leftist, I desire revolutionary change and see such transformation as necessary before this framework of consent can fully hold true. Today, the drive to filter out politics often stems from alienation or reactionary thinking—a symptom of a capitalist system designed to depoliticize and pacify the masses. That's why I object to blanket policies like "No Politics" Rules that promote political apathy.

Radicalization

"Radicalization" is a nebulous term that's been used for a variety of purposes. The ACLU, for example, warns against its usage by saying this:

The government’s “radicalization” theory has become a euphemism for religious and ideological profiling. It leads to discrimination and stigmatization, and is fundamentally un-American. Casting suspicion on American faith or belief communities is wrong and does nothing to make us safer.

Personally, I think the term has been decontextualized a bit, as I see it used today to describe people moving to the left or right. In leftist communities, sharing "what radicalized you" is commonplace and not stigmatized. I think what most accurately describes radicalization is that it's the process of people moving outside the spectrum of acceptable opinion, which in American politics goes from the Republican part to the Democratic party. All other opinions are largely seen as extremist or otherwise untenable. Noam Chomsky describes how this framing perpetuates itself like this:

The smart way to keep people passive and obedient is to strictly limit the spectrum of acceptable opinion, but allow very lively debate within that spectrum—even encourage the more critical and dissident views. That gives people the sense that there's free thinking going on, while all the time the presuppositions of the system are being reinforced by the limits put on the range of the debate. - Noam Chomsky

So, personally, I don't see radicalization as an inherent issue because the current spectrum of acceptable opinion is atrocious (and, separately, an example of a filter bubble that encapsulates most of the US). I'm biased, as by my own definition I'm a radical, but I don't think radicalization should be a reason to fight against filter bubbles. Suppressing it is ultimately a way of enforcing the status quo and enabling those at the top of the status quo to perpetuate their reign.

Of course, I do want to stop people from radicalizing towards fascism. But the solution isn't to restrict all "extremist" content so that only the acceptable opinions are allowed, because fascism is acceptable! The spectrum I've been discussing is so far right that fascist and genocidal rhetoric are normal in our presidential elections and takes like "I won't vote for genocide" are met with "but ending the genocide isn't on the table". Combatting extremism explicitly means supporting our rightwards trend towards fascism.

Jubilee exemplifies the issues I'm discussing here with shows like "middle ground". Besides their clear bias in picking media trained individuals for the right but not the left, they also place the "middle ground" as being between the far right position and a moderate/central position. Funnily enough, it's a great example of why middle grounds as a concept are not intrinsically better than the extremes, as often claimed (again, in defense of the status quo). Drawing a middle point is arbitrary and tied to whatever the currently established spectrum of acceptable opinion happens to be. I recommend this podcast episode that explores the issues with Jubilee and the "free market of ideas". Naturally, they also uphold the principle that marginalized groups should be expected to relive their traumatic experiences with those who wish them harm, under the justification that democracy falls without that.

Echo Chambers vs Filter Bubbles

I've been mostly referring to filter bubbles all this time, but it's time to make an important distinction that will really tie this whole thing together. Filter bubbles are simply having preferences towards the kind of content you see being reflected by algorithms. They can be emergent or intentional, are often innocuous and even helpful, and sometimes may be bad. They have no intrinsic moral value.

Echo Chambers is the term for when filter bubbles turn bad. This is the term for when those inside a filter bubble turn against those outside it. When the only portrayal of those outside the bubble are hateful caricatures from those within it. This is truly where the hateful content and misinformation comes from. Echo Chambers are the problem to solve. But since they're composed of two parts - filter bubbles and hateful content and misinformation - we have a choice for approaching the problem.

Traditionally, people argue the solution to echo chambers is removing the filter bubbles. That if people are simply exposed to more ideas, the echo chamber goes away. As discussed earlier, this cannot be accepted when some of those ideas actively wish harm upon you.

The other approach is just solving the issues with misinformation and hateful content directly. They cannot be tolerated, and should be entirely suppressed. Free speech should not protect people actively doing harm upon others.

Moderating away hate and misinformation

So if the issue isn't the filter bubbles but rather hateful content and misinformation... what do we do to combat it?

On an individual level, we can try to improve our media literacy and spread accurate information with positive values like DEI and class consciousness. Every person counts, although the system is working against us currently.

On a systemic level, a new social media can be designed so they are more protected from misinformation spreading. For example, by allowing users to publicly "vouch" for other users for writing and sharing accurate posts, forming a web of trust/reputation. Also designing the network so those who are popular are not prioritized in algorithmic feeds, essentially centralizing influence into the hands of the few. I explore this topic and other aspects to a radical new social media network in Fedi v2 and Digital Locality.

Taking a step back, several of these issues described - clickbait and spam, specifically - only exist due to financial incentives brought on by our capitalist system. Additionally, Capitalism is the reason for people not having the time, energy, or motivation to more healthily approach social media and combat misinformation. Therefore, we need a Leftist shift to fix these problems and bring us to a more media literate society free of influencers and advertisers. It's the only long term solution.

Message gardening

This is largely theoretical, but something I've been thinking of a lot about are Digital Gardens, and I think the philosophy of them could lead to a different kind of solution to tackling hate and misinformation. Right now a lot of news and discourse about said news is essentially frozen in time. Corrections to stories never get as much attention as the original incorrect story. We have the same discussions over and over again. I thinking we could improve this situation by explicitly framing social media as a tool for building a network of knowledge, like a wiki (or rather, a communal digital garden).

This is something that would need to be explored more before it could be implemented, but I'm sort of envisioning something like twitter's community notes system alongside something like Commune where informal discussions are part of a process of continuously updating a formal document about the topic/event, with new developments, perspectives, and context. I think structuring social media this way, and updating people of important changes to these formal documents people have read or participated in, could lead to a more well informed populace.

Further Reading

Everything discussed in this article falls under the field of sociology, so you may be interested in looking more into that study. I recommend a few of the games by Nicky Case, which share a common thread of exploring sociological concepts:

',47),y=JSON.parse('{"title":"Filter Bubbles","description":"","frontmatter":{"alias":"Echo Chambers","public":"true","slug":"filter-bubbles","title":"Filter Bubbles","prev":false,"next":false},"headers":[],"relativePath":"garden/filter-bubbles/index.md","filePath":"garden/filter-bubbles/index.md"}'),u={name:"garden/filter-bubbles/index.md"},w=Object.assign(u,{setup(p){const a=o();return(m,b)=>(l(),r("div",null,[h,e("p",null,[s("2668 words, ~15 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),d]))}});export{y as __pageData,w as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as r,Q as e,K as s,u as t,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Filter Bubbles",-1),c=["innerHTML"],d=n('
Referenced by:Digital LocalityObjectivity

Filter bubbles refer to how users may be intellectually isolated as a result of Social Media with algorithmic feeds, coupled with things like personalized search engine results and other services catering to someone's existing preferences and world views.

Are you in a filter bubble?

Absolutely, and without a doubt. Filter bubbles fractal inside each other, and most of them are entirely innocuous - they're not the scary boogeyman they've been portrayed as. If your search results are primarily English - you may be in a filter bubble. If the news you watch covers domestic issues within your country more than domestic issues in other countries - you may be in a filter bubble. If the local news you watch covers the weather in your local area but not in areas halfway across the globe - you may be in a filter bubble. These are not significantly contributing to the "intellectual isolation" filter bubbles are said to create, and no one is arguing we must be equally aware of the local weather across the world.

So yes, you're in a filter bubble - likely many, even. But that's not the right question to be asking; We must delve deeper into filter bubbles' causes and manifestations to determine what their negative aspects are and ultimately how to fix them.

Filter bubbles in search engines

The author of The Filter Bubble describes what is supposed to be a chilling story of a search for BP giving results on investment opportunities to one person, and news about the oil spill disaster to another. They posit this is indicative of a problem, but I question that the personalized search results did anything wrong here. Searching BP just by itself is a "neutral" search, and so I think its fine for it to have shown results based on what its learned that user usually looks companies up for. The implication is that the former is an individual who regularly searches companies to see their current investment opportunities, and got what they wanted. If this person were to suddenly want to, say, write a report on BP's history or ecological impact, they'd naturally search for something more specific than just "BP", and certainly find the results they're looking for. And of course, there's layers to this - Google is also figuring out what search results the average person usually wants when searching a given term, and ranking those higher. So the more people search for BP to get info on the disaster, the more prominent that disaster will be.

The problems stem from the various biases we all bring with us when researching anything, whether we're in a filter bubble or not. In this regard, filter bubbles are just automated applications of our own biases. For example, if you're researching the impact of the BP ecological disaster, your pre-conceived notions over its impact - and perhaps your personal financial interests - will dictate which sources you read at all, or ultimately decide to reference or ignore when discussing the issue with others. And to be clear, all sources will have a bias. There is no such thing as Objectivity, and even seemingly "neutral" outlets are implicitly defending the status quo of society.

I think most of you may relate to this, because we're all guilty of it, myself included. I've certainly shared news articles based on the headline, and perhaps even spend a bit too much time writing and not enough reading. Research papers in particular are incredibly dry and most people will only read articles about the paper, which may not be accurate, or perhaps only read the abstract, which may not be thorough. I'm keenly aware when citing a source that its unlikely someone will actually follow that link, to the point where it almost feels futile. Perhaps even now you're only skimming this page? Taken together, it seems an article existing with a given headline is more important than any arguments held within it.

Filter bubbles in social media

The more insidious issue of filter bubbles is when it applies passively, such as when you're on social media and simply don't see anything about an important topic, say the BP oil spill. But actually, part of the issue here isn't just not seeing the post, as even if someone sees posts about the event, they may be tainted with biases towards their existing world view, and the reader will just accept that interpretation at face value. After all, most users are not going to see a headline and start doing independent research to verify the claims held within the article. Hell, most won't even go as far as reading the article itself - as has been studied many times, sometimes in quite amusing widely shared but fake "prank" articles.

Even if you click a link, you may just skim the results. This is a problem because people are not reading articles to actually learn from them, but rather to confirm their pre-existing opinions on the topic. With that reassurance in hand, they'll share the articles and feel more confident they actually understand the topic.

A lot of the articles even available to share on social media are being crafted especially to be sharable using clickbait, caring more for covering topics profitably rather than ethically. AI slop has significantly compounded this issue by being able to mass produce articles that wholly lack meaningful insight, and is now a major problem for both search engines and social media platforms.

All the biases described above contribute to an especially problematic aspect of filter bubbles: the spreading of misinformation. If people are unwilling to verify provocative but ultimately wrong claims they read in a headline, then how do we fix that? There are different approaches people have suggested: algorithmic suppression by a independent organization tasked with verifying articles' legitimacy like Facebook, relying on community-driven notes like Twitter, or just trying to shift the culture to engage with social media more productively/healthily.

Are safe spaces filter bubbles?

The internet is a dangerous place, especially for members of marginalized groups. There are a lot of -phobes in the world, and the internet gives them a platform to harass far more widespread than before. It takes concerted effort to keep them out of communities, as described by Innuendo Studios' How to radicalize a normie. I think we should all be in agreement that it is entirely fine for people to want to filter out this kind of hateful content. So safe spaces are filter bubbles, but also are good and important things to have access to.

I bring this up to really drive home that filter bubbles are not intrinsically good or bad. They happen innocuously and are even beneficial for filtering out certain kinds of content. It's important any solution to the issues with filter bubbles focuses doesn't involve exposing people to, say, those who'd like to see them dead.

The line doesn't have to be at hateful content though. There's any number of content someone may want to filter out - gore, SA, or other PTSD triggers. Ultimately the line is subjective, and where the line is shouldn't be restricted or imposed. Empathy is the key here, and the same way a trans person shouldn't be encouraged to interact with transphobes, no one should be encouraged to engage in any social interactions they deem uncomfortable, even if others don't think it's uncomfortable.

Filtering politics

In the previous section I proposed that allowing people to decide what they want to see should is important. Most people can, I imagine, agree with that, barring one notable and often contested exception: politics. Our liberal democracy insists that universal political engagement is required for it to function properly. While I agree politics are critically important, politics should not be an exception that people "must" be subjected to regardless of their consent.

A lot of political topics are deeply personal and emotionally exhausting to engage with, particularly for those marginalized under the current power structures. For example, trans rights are an extremely important political issue, but demanding that trans people continually defend their very existence against reactionary attacks amounts to a form of re-traumatization. People not being exposed to these kinds of upsetting things is not a problem to be solved, and democracy can survive while allowing people to filter out political topics or perspectives they don't want to see. You do not need to tolerate the intolerant (as argued by Karl Popper, who coined the term "paradox of tolerance").

Admittedly, as a Leftist, I desire revolutionary change and see such transformation as necessary before this framework of consent can fully hold true. Today, the drive to filter out politics often stems from alienation or reactionary thinking—a symptom of a capitalist system designed to depoliticize and pacify the masses. That's why I object to blanket policies like "No Politics" Rules that promote political apathy.

Radicalization

"Radicalization" is a nebulous term that's been used for a variety of purposes. The ACLU, for example, warns against its usage by saying this:

The government’s “radicalization” theory has become a euphemism for religious and ideological profiling. It leads to discrimination and stigmatization, and is fundamentally un-American. Casting suspicion on American faith or belief communities is wrong and does nothing to make us safer.

Personally, I think the term has been decontextualized a bit, as I see it used today to describe people moving to the left or right. In leftist communities, sharing "what radicalized you" is commonplace and not stigmatized. I think what most accurately describes radicalization is that it's the process of people moving outside the spectrum of acceptable opinion, which in American politics goes from the Republican part to the Democratic party. All other opinions are largely seen as extremist or otherwise untenable. Noam Chomsky describes how this framing perpetuates itself like this:

The smart way to keep people passive and obedient is to strictly limit the spectrum of acceptable opinion, but allow very lively debate within that spectrum—even encourage the more critical and dissident views. That gives people the sense that there's free thinking going on, while all the time the presuppositions of the system are being reinforced by the limits put on the range of the debate. - Noam Chomsky

So, personally, I don't see radicalization as an inherent issue because the current spectrum of acceptable opinion is atrocious (and, separately, an example of a filter bubble that encapsulates most of the US). I'm biased, as by my own definition I'm a radical, but I don't think radicalization should be a reason to fight against filter bubbles. Suppressing it is ultimately a way of enforcing the status quo and enabling those at the top of the status quo to perpetuate their reign.

Of course, I do want to stop people from radicalizing towards fascism. But the solution isn't to restrict all "extremist" content so that only the acceptable opinions are allowed, because fascism is acceptable! The spectrum I've been discussing is so far right that fascist and genocidal rhetoric are normal in our presidential elections and takes like "I won't vote for genocide" are met with "but ending the genocide isn't on the table". Combatting extremism explicitly means supporting our rightwards trend towards fascism.

Jubilee exemplifies the issues I'm discussing here with shows like "middle ground". Besides their clear bias in picking media trained individuals for the right but not the left, they also place the "middle ground" as being between the far right position and a moderate/central position. Funnily enough, it's a great example of why middle grounds as a concept are not intrinsically better than the extremes, as often claimed (again, in defense of the status quo). Drawing a middle point is arbitrary and tied to whatever the currently established spectrum of acceptable opinion happens to be. I recommend this podcast episode that explores the issues with Jubilee and the "free market of ideas". Naturally, they also uphold the principle that marginalized groups should be expected to relive their traumatic experiences with those who wish them harm, under the justification that democracy falls without that.

Echo Chambers vs Filter Bubbles

I've been mostly referring to filter bubbles all this time, but it's time to make an important distinction that will really tie this whole thing together. Filter bubbles are simply having preferences towards the kind of content you see being reflected by algorithms. They can be emergent or intentional, are often innocuous and even helpful, and sometimes may be bad. They have no intrinsic moral value.

Echo Chambers is the term for when filter bubbles turn bad. This is the term for when those inside a filter bubble turn against those outside it. When the only portrayal of those outside the bubble are hateful caricatures from those within it. This is truly where the hateful content and misinformation comes from. Echo Chambers are the problem to solve. But since they're composed of two parts - filter bubbles and hateful content and misinformation - we have a choice for approaching the problem.

Traditionally, people argue the solution to echo chambers is removing the filter bubbles. That if people are simply exposed to more ideas, the echo chamber goes away. As discussed earlier, this cannot be accepted when some of those ideas actively wish harm upon you.

The other approach is just solving the issues with misinformation and hateful content directly. They cannot be tolerated, and should be entirely suppressed. Free speech should not protect people actively doing harm upon others.

Moderating away hate and misinformation

So if the issue isn't the filter bubbles but rather hateful content and misinformation... what do we do to combat it?

On an individual level, we can try to improve our media literacy and spread accurate information with positive values like DEI and class consciousness. Every person counts, although the system is working against us currently.

On a systemic level, a new social media can be designed so they are more protected from misinformation spreading. For example, by allowing users to publicly "vouch" for other users for writing and sharing accurate posts, forming a web of trust/reputation. Also designing the network so those who are popular are not prioritized in algorithmic feeds, essentially centralizing influence into the hands of the few. I explore this topic and other aspects to a radical new social media network in Fedi v2 and Digital Locality.

Taking a step back, several of these issues described - clickbait and spam, specifically - only exist due to financial incentives brought on by our capitalist system. Additionally, Capitalism is the reason for people not having the time, energy, or motivation to more healthily approach social media and combat misinformation. Therefore, we need a Leftist shift to fix these problems and bring us to a more media literate society free of influencers and advertisers. It's the only long term solution.

Message gardening

This is largely theoretical, but something I've been thinking of a lot about are Digital Gardens, and I think the philosophy of them could lead to a different kind of solution to tackling hate and misinformation. Right now a lot of news and discourse about said news is essentially frozen in time. Corrections to stories never get as much attention as the original incorrect story. We have the same discussions over and over again. I thinking we could improve this situation by explicitly framing social media as a tool for building a network of knowledge, like a wiki (or rather, a communal digital garden).

This is something that would need to be explored more before it could be implemented, but I'm sort of envisioning something like twitter's community notes system alongside something like Commune where informal discussions are part of a process of continuously updating a formal document about the topic/event, with new developments, perspectives, and context. I think structuring social media this way, and updating people of important changes to these formal documents people have read or participated in, could lead to a more well informed populace.

Further Reading

Everything discussed in this article falls under the field of sociology, so you may be interested in looking more into that study. I recommend a few of the games by Nicky Case, which share a common thread of exploring sociological concepts:

',47),y=JSON.parse('{"title":"Filter Bubbles","description":"","frontmatter":{"alias":"Echo Chambers","public":"true","slug":"filter-bubbles","title":"Filter Bubbles","prev":false,"next":false},"headers":[],"relativePath":"garden/filter-bubbles/index.md","filePath":"garden/filter-bubbles/index.md"}'),u={name:"garden/filter-bubbles/index.md"},w=Object.assign(u,{setup(p){const a=o();return(m,b)=>(l(),r("div",null,[h,e("p",null,[s("2668 words, ~15 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),d]))}});export{y as __pageData,w as default}; diff --git a/assets/garden_filter-bubbles_index.md.-FC6NYD-.lean.js b/assets/garden_filter-bubbles_index.md.qLDBKf98.lean.js similarity index 92% rename from assets/garden_filter-bubbles_index.md.-FC6NYD-.lean.js rename to assets/garden_filter-bubbles_index.md.qLDBKf98.lean.js index e92b60a9d..0ead14dc4 100644 --- a/assets/garden_filter-bubbles_index.md.-FC6NYD-.lean.js +++ b/assets/garden_filter-bubbles_index.md.qLDBKf98.lean.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as r,Q as e,K as s,u as t,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Filter Bubbles",-1),c=["innerHTML"],d=n("",47),y=JSON.parse('{"title":"Filter Bubbles","description":"","frontmatter":{"alias":"Echo Chambers","public":"true","slug":"filter-bubbles","title":"Filter Bubbles","prev":false,"next":false},"headers":[],"relativePath":"garden/filter-bubbles/index.md","filePath":"garden/filter-bubbles/index.md"}'),u={name:"garden/filter-bubbles/index.md"},w=Object.assign(u,{setup(p){const a=o();return(m,b)=>(l(),r("div",null,[h,e("p",null,[s("2668 words, ~15 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),d]))}});export{y as __pageData,w as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as r,Q as e,K as s,u as t,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Filter Bubbles",-1),c=["innerHTML"],d=n("",47),y=JSON.parse('{"title":"Filter Bubbles","description":"","frontmatter":{"alias":"Echo Chambers","public":"true","slug":"filter-bubbles","title":"Filter Bubbles","prev":false,"next":false},"headers":[],"relativePath":"garden/filter-bubbles/index.md","filePath":"garden/filter-bubbles/index.md"}'),u={name:"garden/filter-bubbles/index.md"},w=Object.assign(u,{setup(p){const a=o();return(m,b)=>(l(),r("div",null,[h,e("p",null,[s("2668 words, ~15 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),d]))}});export{y as __pageData,w as default}; diff --git a/assets/garden_forgejo_index.md.GiARxfDT.js b/assets/garden_forgejo_index.md.4kXC1s_Z.js similarity index 94% rename from assets/garden_forgejo_index.md.GiARxfDT.js rename to assets/garden_forgejo_index.md.4kXC1s_Z.js index 595c7b6e2..aaada9173 100644 --- a/assets/garden_forgejo_index.md.GiARxfDT.js +++ b/assets/garden_forgejo_index.md.4kXC1s_Z.js @@ -1 +1 @@ -import{d as o}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as s,Q as e,K as a,u as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"Forgejo",-1),d=["innerHTML"],c=e("hr",null,null,-1),u=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social")],-1),p=e("p",null,[e("a",{href:"https://forgejo.org",target:"_blank",rel:"noreferrer"},"Forgejo"),a(" is an "),e("a",{href:"/garden/open-source/"},"Open Source"),a(" code repository hosting software")],-1),x=JSON.parse('{"title":"Forgejo","description":"","frontmatter":{"public":"true","slug":"forgejo","title":"Forgejo","prev":false,"next":false},"headers":[],"relativePath":"garden/forgejo/index.md","filePath":"garden/forgejo/index.md"}'),_={name:"garden/forgejo/index.md"},v=Object.assign(_,{setup(g){const t=n();return(f,m)=>(l(),s("div",null,[i,e("p",null,[a("5 words, ~0 minute read. "),e("span",{innerHTML:r(o)[`site/${r(t).page.value.relativePath}`]},null,8,d)]),c,u,p]))}});export{x as __pageData,v as default}; +import{d as o}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as s,Q as e,K as a,u as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"Forgejo",-1),d=["innerHTML"],c=e("hr",null,null,-1),u=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social")],-1),p=e("p",null,[e("a",{href:"https://forgejo.org",target:"_blank",rel:"noreferrer"},"Forgejo"),a(" is an "),e("a",{href:"/garden/open-source/"},"Open Source"),a(" code repository hosting software")],-1),x=JSON.parse('{"title":"Forgejo","description":"","frontmatter":{"public":"true","slug":"forgejo","title":"Forgejo","prev":false,"next":false},"headers":[],"relativePath":"garden/forgejo/index.md","filePath":"garden/forgejo/index.md"}'),_={name:"garden/forgejo/index.md"},v=Object.assign(_,{setup(g){const t=n();return(f,m)=>(l(),s("div",null,[i,e("p",null,[a("5 words, ~0 minute read. "),e("span",{innerHTML:r(o)[`site/${r(t).page.value.relativePath}`]},null,8,d)]),c,u,p]))}});export{x as __pageData,v as default}; diff --git a/assets/garden_forgejo_index.md.GiARxfDT.lean.js b/assets/garden_forgejo_index.md.4kXC1s_Z.lean.js similarity index 94% rename from assets/garden_forgejo_index.md.GiARxfDT.lean.js rename to assets/garden_forgejo_index.md.4kXC1s_Z.lean.js index 595c7b6e2..aaada9173 100644 --- a/assets/garden_forgejo_index.md.GiARxfDT.lean.js +++ b/assets/garden_forgejo_index.md.4kXC1s_Z.lean.js @@ -1 +1 @@ -import{d as o}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as s,Q as e,K as a,u as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"Forgejo",-1),d=["innerHTML"],c=e("hr",null,null,-1),u=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social")],-1),p=e("p",null,[e("a",{href:"https://forgejo.org",target:"_blank",rel:"noreferrer"},"Forgejo"),a(" is an "),e("a",{href:"/garden/open-source/"},"Open Source"),a(" code repository hosting software")],-1),x=JSON.parse('{"title":"Forgejo","description":"","frontmatter":{"public":"true","slug":"forgejo","title":"Forgejo","prev":false,"next":false},"headers":[],"relativePath":"garden/forgejo/index.md","filePath":"garden/forgejo/index.md"}'),_={name:"garden/forgejo/index.md"},v=Object.assign(_,{setup(g){const t=n();return(f,m)=>(l(),s("div",null,[i,e("p",null,[a("5 words, ~0 minute read. "),e("span",{innerHTML:r(o)[`site/${r(t).page.value.relativePath}`]},null,8,d)]),c,u,p]))}});export{x as __pageData,v as default}; +import{d as o}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as s,Q as e,K as a,u as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"Forgejo",-1),d=["innerHTML"],c=e("hr",null,null,-1),u=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social")],-1),p=e("p",null,[e("a",{href:"https://forgejo.org",target:"_blank",rel:"noreferrer"},"Forgejo"),a(" is an "),e("a",{href:"/garden/open-source/"},"Open Source"),a(" code repository hosting software")],-1),x=JSON.parse('{"title":"Forgejo","description":"","frontmatter":{"public":"true","slug":"forgejo","title":"Forgejo","prev":false,"next":false},"headers":[],"relativePath":"garden/forgejo/index.md","filePath":"garden/forgejo/index.md"}'),_={name:"garden/forgejo/index.md"},v=Object.assign(_,{setup(g){const t=n();return(f,m)=>(l(),s("div",null,[i,e("p",null,[a("5 words, ~0 minute read. "),e("span",{innerHTML:r(o)[`site/${r(t).page.value.relativePath}`]},null,8,d)]),c,u,p]))}});export{x as __pageData,v as default}; diff --git a/assets/garden_freeform-vs-chronological-dichotomy_index.md.DYWAb1HB.js b/assets/garden_freeform-vs-chronological-dichotomy_index.md.Bc4Lj93E.js similarity index 95% rename from assets/garden_freeform-vs-chronological-dichotomy_index.md.DYWAb1HB.js rename to assets/garden_freeform-vs-chronological-dichotomy_index.md.Bc4Lj93E.js index 2e6caae43..3de706231 100644 --- a/assets/garden_freeform-vs-chronological-dichotomy_index.md.DYWAb1HB.js +++ b/assets/garden_freeform-vs-chronological-dichotomy_index.md.Bc4Lj93E.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as t,q as l,Q as e,K as o,u as r,p as i}from"./chunks/framework.Sr2_9k8k.js";const s=e("h1",{class:"p-name"},"Freeform vs Chronological Dichotomy",-1),c=["innerHTML"],d=e("hr",null,null,-1),m=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/chronological/index.md"},"Chronological"),e("a",{href:"/garden/freeform/index.md"},"Freeform")],-1),h=e("p",null,[o("Describes a dichotomy between displaying information in a "),e("a",{href:"/garden/freeform/"},"Freeform"),o(" vs "),e("a",{href:"/garden/chronological/"},"Chronological"),o(" manner")],-1),y=JSON.parse('{"title":"Freeform vs Chronological Dichotomy","description":"","frontmatter":{"public":"true","slug":"freeform-vs-chronological-dichotomy","title":"Freeform vs Chronological Dichotomy","prev":false,"next":false},"headers":[],"relativePath":"garden/freeform-vs-chronological-dichotomy/index.md","filePath":"garden/freeform-vs-chronological-dichotomy/index.md"}'),f={name:"garden/freeform-vs-chronological-dichotomy/index.md"},x=Object.assign(f,{setup(g){const a=t();return(u,_)=>(i(),l("div",null,[s,e("p",null,[o("10 words, ~0 minute read. "),e("span",{innerHTML:r(n)[`site/${r(a).page.value.relativePath}`]},null,8,c)]),d,m,h]))}});export{y as __pageData,x as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as t,q as l,Q as e,K as o,u as r,p as i}from"./chunks/framework.Sr2_9k8k.js";const s=e("h1",{class:"p-name"},"Freeform vs Chronological Dichotomy",-1),c=["innerHTML"],d=e("hr",null,null,-1),m=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/chronological/index.md"},"Chronological"),e("a",{href:"/garden/freeform/index.md"},"Freeform")],-1),h=e("p",null,[o("Describes a dichotomy between displaying information in a "),e("a",{href:"/garden/freeform/"},"Freeform"),o(" vs "),e("a",{href:"/garden/chronological/"},"Chronological"),o(" manner")],-1),y=JSON.parse('{"title":"Freeform vs Chronological Dichotomy","description":"","frontmatter":{"public":"true","slug":"freeform-vs-chronological-dichotomy","title":"Freeform vs Chronological Dichotomy","prev":false,"next":false},"headers":[],"relativePath":"garden/freeform-vs-chronological-dichotomy/index.md","filePath":"garden/freeform-vs-chronological-dichotomy/index.md"}'),f={name:"garden/freeform-vs-chronological-dichotomy/index.md"},x=Object.assign(f,{setup(g){const a=t();return(u,_)=>(i(),l("div",null,[s,e("p",null,[o("10 words, ~0 minute read. "),e("span",{innerHTML:r(n)[`site/${r(a).page.value.relativePath}`]},null,8,c)]),d,m,h]))}});export{y as __pageData,x as default}; diff --git a/assets/garden_freeform-vs-chronological-dichotomy_index.md.DYWAb1HB.lean.js b/assets/garden_freeform-vs-chronological-dichotomy_index.md.Bc4Lj93E.lean.js similarity index 95% rename from assets/garden_freeform-vs-chronological-dichotomy_index.md.DYWAb1HB.lean.js rename to assets/garden_freeform-vs-chronological-dichotomy_index.md.Bc4Lj93E.lean.js index 2e6caae43..3de706231 100644 --- a/assets/garden_freeform-vs-chronological-dichotomy_index.md.DYWAb1HB.lean.js +++ b/assets/garden_freeform-vs-chronological-dichotomy_index.md.Bc4Lj93E.lean.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as t,q as l,Q as e,K as o,u as r,p as i}from"./chunks/framework.Sr2_9k8k.js";const s=e("h1",{class:"p-name"},"Freeform vs Chronological Dichotomy",-1),c=["innerHTML"],d=e("hr",null,null,-1),m=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/chronological/index.md"},"Chronological"),e("a",{href:"/garden/freeform/index.md"},"Freeform")],-1),h=e("p",null,[o("Describes a dichotomy between displaying information in a "),e("a",{href:"/garden/freeform/"},"Freeform"),o(" vs "),e("a",{href:"/garden/chronological/"},"Chronological"),o(" manner")],-1),y=JSON.parse('{"title":"Freeform vs Chronological Dichotomy","description":"","frontmatter":{"public":"true","slug":"freeform-vs-chronological-dichotomy","title":"Freeform vs Chronological Dichotomy","prev":false,"next":false},"headers":[],"relativePath":"garden/freeform-vs-chronological-dichotomy/index.md","filePath":"garden/freeform-vs-chronological-dichotomy/index.md"}'),f={name:"garden/freeform-vs-chronological-dichotomy/index.md"},x=Object.assign(f,{setup(g){const a=t();return(u,_)=>(i(),l("div",null,[s,e("p",null,[o("10 words, ~0 minute read. "),e("span",{innerHTML:r(n)[`site/${r(a).page.value.relativePath}`]},null,8,c)]),d,m,h]))}});export{y as __pageData,x as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as t,q as l,Q as e,K as o,u as r,p as i}from"./chunks/framework.Sr2_9k8k.js";const s=e("h1",{class:"p-name"},"Freeform vs Chronological Dichotomy",-1),c=["innerHTML"],d=e("hr",null,null,-1),m=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/chronological/index.md"},"Chronological"),e("a",{href:"/garden/freeform/index.md"},"Freeform")],-1),h=e("p",null,[o("Describes a dichotomy between displaying information in a "),e("a",{href:"/garden/freeform/"},"Freeform"),o(" vs "),e("a",{href:"/garden/chronological/"},"Chronological"),o(" manner")],-1),y=JSON.parse('{"title":"Freeform vs Chronological Dichotomy","description":"","frontmatter":{"public":"true","slug":"freeform-vs-chronological-dichotomy","title":"Freeform vs Chronological Dichotomy","prev":false,"next":false},"headers":[],"relativePath":"garden/freeform-vs-chronological-dichotomy/index.md","filePath":"garden/freeform-vs-chronological-dichotomy/index.md"}'),f={name:"garden/freeform-vs-chronological-dichotomy/index.md"},x=Object.assign(f,{setup(g){const a=t();return(u,_)=>(i(),l("div",null,[s,e("p",null,[o("10 words, ~0 minute read. "),e("span",{innerHTML:r(n)[`site/${r(a).page.value.relativePath}`]},null,8,c)]),d,m,h]))}});export{y as __pageData,x as default}; diff --git a/assets/garden_freeform_index.md.DrTiVQ1a.js b/assets/garden_freeform_index.md.CLFdmYH0.js similarity index 95% rename from assets/garden_freeform_index.md.DrTiVQ1a.js rename to assets/garden_freeform_index.md.CLFdmYH0.js index 74ecf864d..3650c3c5e 100644 --- a/assets/garden_freeform_index.md.DrTiVQ1a.js +++ b/assets/garden_freeform_index.md.CLFdmYH0.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as n,Q as e,K as i,u as a,ag as s,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Freeform",-1),m=["innerHTML"],c=s('
Referenced by:CommuneDigital GardensFreeform vs Chronological DichotomyGarden-RSS

A collection of information that is not tied to when it was created or edited

Part of the Freeform vs Chronological Dichotomy

Anything wiki-style is considered freeform

  • A collection of living documents

Garden-RSS, a theoretical alternative to RSS that's better for freeform content

',7),v=JSON.parse('{"title":"Freeform","description":"","frontmatter":{"public":"true","slug":"freeform","title":"Freeform","prev":false,"next":false},"headers":[],"relativePath":"garden/freeform/index.md","filePath":"garden/freeform/index.md"}'),f={name:"garden/freeform/index.md"},x=Object.assign(f,{setup(h){const r=o();return(_,g)=>(d(),n("div",null,[l,e("p",null,[i("46 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,m)]),c]))}});export{v as __pageData,x as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as n,Q as e,K as i,u as a,ag as s,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Freeform",-1),m=["innerHTML"],c=s('
Referenced by:CommuneDigital GardensFreeform vs Chronological DichotomyGarden-RSS

A collection of information that is not tied to when it was created or edited

Part of the Freeform vs Chronological Dichotomy

Anything wiki-style is considered freeform

  • A collection of living documents

Garden-RSS, a theoretical alternative to RSS that's better for freeform content

',7),v=JSON.parse('{"title":"Freeform","description":"","frontmatter":{"public":"true","slug":"freeform","title":"Freeform","prev":false,"next":false},"headers":[],"relativePath":"garden/freeform/index.md","filePath":"garden/freeform/index.md"}'),f={name:"garden/freeform/index.md"},x=Object.assign(f,{setup(h){const r=o();return(_,g)=>(d(),n("div",null,[l,e("p",null,[i("46 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,m)]),c]))}});export{v as __pageData,x as default}; diff --git a/assets/garden_freeform_index.md.DrTiVQ1a.lean.js b/assets/garden_freeform_index.md.CLFdmYH0.lean.js similarity index 91% rename from assets/garden_freeform_index.md.DrTiVQ1a.lean.js rename to assets/garden_freeform_index.md.CLFdmYH0.lean.js index c577b81bf..47b70d6bb 100644 --- a/assets/garden_freeform_index.md.DrTiVQ1a.lean.js +++ b/assets/garden_freeform_index.md.CLFdmYH0.lean.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as n,Q as e,K as i,u as a,ag as s,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Freeform",-1),m=["innerHTML"],c=s("",7),v=JSON.parse('{"title":"Freeform","description":"","frontmatter":{"public":"true","slug":"freeform","title":"Freeform","prev":false,"next":false},"headers":[],"relativePath":"garden/freeform/index.md","filePath":"garden/freeform/index.md"}'),f={name:"garden/freeform/index.md"},x=Object.assign(f,{setup(h){const r=o();return(_,g)=>(d(),n("div",null,[l,e("p",null,[i("46 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,m)]),c]))}});export{v as __pageData,x as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as n,Q as e,K as i,u as a,ag as s,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Freeform",-1),m=["innerHTML"],c=s("",7),v=JSON.parse('{"title":"Freeform","description":"","frontmatter":{"public":"true","slug":"freeform","title":"Freeform","prev":false,"next":false},"headers":[],"relativePath":"garden/freeform/index.md","filePath":"garden/freeform/index.md"}'),f={name:"garden/freeform/index.md"},x=Object.assign(f,{setup(h){const r=o();return(_,g)=>(d(),n("div",null,[l,e("p",null,[i("46 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,m)]),c]))}});export{v as __pageData,x as default}; diff --git a/assets/garden_game-dev-tree_index.md.YpLH-Pt3.js b/assets/garden_game-dev-tree_index.md.BYDVgNyE.js similarity index 95% rename from assets/garden_game-dev-tree_index.md.YpLH-Pt3.js rename to assets/garden_game-dev-tree_index.md.BYDVgNyE.js index 01cbdd3a5..ae4887524 100644 --- a/assets/garden_game-dev-tree_index.md.YpLH-Pt3.js +++ b/assets/garden_game-dev-tree_index.md.BYDVgNyE.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as o,Q as e,K as n,u as a,ag as p,p as i}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Game Dev Tree",-1),m=["innerHTML"],l=p('
Tags:My Projects

Play it here!

My first (good) incremental game! (My actual first was Shape Tycoon - I don't recommend it!)

It's Open Source!

The TV Tropes page on this game mentions some of the cool things about this game

',6),T=JSON.parse('{"title":"Game Dev Tree","description":"","frontmatter":{"public":"true","slug":"game-dev-tree","tags":["My Projects"],"title":"Game Dev Tree","prev":false,"next":false},"headers":[],"relativePath":"garden/game-dev-tree/index.md","filePath":"garden/game-dev-tree/index.md"}'),c={name:"garden/game-dev-tree/index.md"},v=Object.assign(c,{setup(_){const t=s();return(h,g)=>(i(),o("div",null,[d,e("p",null,[n("34 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),l]))}});export{T as __pageData,v as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as o,Q as e,K as n,u as a,ag as p,p as i}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Game Dev Tree",-1),m=["innerHTML"],l=p('
Tags:My Projects

Play it here!

My first (good) incremental game! (My actual first was Shape Tycoon - I don't recommend it!)

It's Open Source!

The TV Tropes page on this game mentions some of the cool things about this game

',6),T=JSON.parse('{"title":"Game Dev Tree","description":"","frontmatter":{"public":"true","slug":"game-dev-tree","tags":["My Projects"],"title":"Game Dev Tree","prev":false,"next":false},"headers":[],"relativePath":"garden/game-dev-tree/index.md","filePath":"garden/game-dev-tree/index.md"}'),c={name:"garden/game-dev-tree/index.md"},v=Object.assign(c,{setup(_){const t=s();return(h,g)=>(i(),o("div",null,[d,e("p",null,[n("34 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),l]))}});export{T as __pageData,v as default}; diff --git a/assets/garden_game-dev-tree_index.md.YpLH-Pt3.lean.js b/assets/garden_game-dev-tree_index.md.BYDVgNyE.lean.js similarity index 91% rename from assets/garden_game-dev-tree_index.md.YpLH-Pt3.lean.js rename to assets/garden_game-dev-tree_index.md.BYDVgNyE.lean.js index 5a5c8ae41..54146f48a 100644 --- a/assets/garden_game-dev-tree_index.md.YpLH-Pt3.lean.js +++ b/assets/garden_game-dev-tree_index.md.BYDVgNyE.lean.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as o,Q as e,K as n,u as a,ag as p,p as i}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Game Dev Tree",-1),m=["innerHTML"],l=p("",6),T=JSON.parse('{"title":"Game Dev Tree","description":"","frontmatter":{"public":"true","slug":"game-dev-tree","tags":["My Projects"],"title":"Game Dev Tree","prev":false,"next":false},"headers":[],"relativePath":"garden/game-dev-tree/index.md","filePath":"garden/game-dev-tree/index.md"}'),c={name:"garden/game-dev-tree/index.md"},v=Object.assign(c,{setup(_){const t=s();return(h,g)=>(i(),o("div",null,[d,e("p",null,[n("34 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),l]))}});export{T as __pageData,v as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as o,Q as e,K as n,u as a,ag as p,p as i}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Game Dev Tree",-1),m=["innerHTML"],l=p("",6),T=JSON.parse('{"title":"Game Dev Tree","description":"","frontmatter":{"public":"true","slug":"game-dev-tree","tags":["My Projects"],"title":"Game Dev Tree","prev":false,"next":false},"headers":[],"relativePath":"garden/game-dev-tree/index.md","filePath":"garden/game-dev-tree/index.md"}'),c={name:"garden/game-dev-tree/index.md"},v=Object.assign(c,{setup(_){const t=s();return(h,g)=>(i(),o("div",null,[d,e("p",null,[n("34 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),l]))}});export{T as __pageData,v as default}; diff --git a/assets/garden_garden-rss_index.md.AWGxD-E4.js b/assets/garden_garden-rss_index.md.BuAHk1MQ.js similarity index 96% rename from assets/garden_garden-rss_index.md.AWGxD-E4.js rename to assets/garden_garden-rss_index.md.BuAHk1MQ.js index cc051ff25..460bc1dfe 100644 --- a/assets/garden_garden-rss_index.md.AWGxD-E4.js +++ b/assets/garden_garden-rss_index.md.BuAHk1MQ.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as i,Q as e,K as n,u as a,ag as l,p as d}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Garden-RSS",-1),c=["innerHTML"],h=l('
Referenced by:FreeformOrchardThe Small WebThis Knowledge Hub

A theoretical alternative to RSS that's better for Freeform websites (and Digital Gardens specifically )

Why is it useful?

How should it work?

  • Could display changes similar to git diffs

Existing Work

',9),S=JSON.parse('{"title":"Garden-RSS","description":"","frontmatter":{"public":"true","slug":"garden-rss","title":"Garden-RSS","prev":false,"next":false},"headers":[],"relativePath":"garden/garden-rss/index.md","filePath":"garden/garden-rss/index.md"}'),f={name:"garden/garden-rss/index.md"},b=Object.assign(f,{setup(g){const r=s();return(u,m)=>(d(),i("div",null,[o,e("p",null,[n("59 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,c)]),h]))}});export{S as __pageData,b as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as i,Q as e,K as n,u as a,ag as l,p as d}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Garden-RSS",-1),c=["innerHTML"],h=l('
Referenced by:FreeformOrchardThe Small WebThis Knowledge Hub

A theoretical alternative to RSS that's better for Freeform websites (and Digital Gardens specifically )

Why is it useful?

How should it work?

  • Could display changes similar to git diffs

Existing Work

',9),S=JSON.parse('{"title":"Garden-RSS","description":"","frontmatter":{"public":"true","slug":"garden-rss","title":"Garden-RSS","prev":false,"next":false},"headers":[],"relativePath":"garden/garden-rss/index.md","filePath":"garden/garden-rss/index.md"}'),f={name:"garden/garden-rss/index.md"},b=Object.assign(f,{setup(g){const r=s();return(u,m)=>(d(),i("div",null,[o,e("p",null,[n("59 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,c)]),h]))}});export{S as __pageData,b as default}; diff --git a/assets/garden_garden-rss_index.md.AWGxD-E4.lean.js b/assets/garden_garden-rss_index.md.BuAHk1MQ.lean.js similarity index 91% rename from assets/garden_garden-rss_index.md.AWGxD-E4.lean.js rename to assets/garden_garden-rss_index.md.BuAHk1MQ.lean.js index 71e7eb697..7e6c1f27d 100644 --- a/assets/garden_garden-rss_index.md.AWGxD-E4.lean.js +++ b/assets/garden_garden-rss_index.md.BuAHk1MQ.lean.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as i,Q as e,K as n,u as a,ag as l,p as d}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Garden-RSS",-1),c=["innerHTML"],h=l("",9),S=JSON.parse('{"title":"Garden-RSS","description":"","frontmatter":{"public":"true","slug":"garden-rss","title":"Garden-RSS","prev":false,"next":false},"headers":[],"relativePath":"garden/garden-rss/index.md","filePath":"garden/garden-rss/index.md"}'),f={name:"garden/garden-rss/index.md"},b=Object.assign(f,{setup(g){const r=s();return(u,m)=>(d(),i("div",null,[o,e("p",null,[n("59 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,c)]),h]))}});export{S as __pageData,b as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as i,Q as e,K as n,u as a,ag as l,p as d}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Garden-RSS",-1),c=["innerHTML"],h=l("",9),S=JSON.parse('{"title":"Garden-RSS","description":"","frontmatter":{"public":"true","slug":"garden-rss","title":"Garden-RSS","prev":false,"next":false},"headers":[],"relativePath":"garden/garden-rss/index.md","filePath":"garden/garden-rss/index.md"}'),f={name:"garden/garden-rss/index.md"},b=Object.assign(f,{setup(g){const r=s();return(u,m)=>(d(),i("div",null,[o,e("p",null,[n("59 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,c)]),h]))}});export{S as __pageData,b as default}; diff --git a/assets/garden_gender-performativity_index.md.CnW1xA_a.js b/assets/garden_gender-performativity_index.md.s4FTNt-A.js similarity index 95% rename from assets/garden_gender-performativity_index.md.CnW1xA_a.js rename to assets/garden_gender-performativity_index.md.s4FTNt-A.js index bdba0b885..c0bb82eb5 100644 --- a/assets/garden_gender-performativity_index.md.CnW1xA_a.js +++ b/assets/garden_gender-performativity_index.md.s4FTNt-A.js @@ -1 +1 @@ -import{d as a}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as i,Q as e,K as s,u as r,ag as o,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Gender Performativity",-1),m=["innerHTML"],p=o('
Referenced by:ObjectivityPersonality

A Gender theory by Judith Butler, as described in Gender Trouble. Butler argues that we observe gender norms performed by others and reproduce them. In this way, gender is a force that acts upon us. Philosophy Tube describes this theory in more detail in I read the most misunderstood philosopher in the world

',3),y=JSON.parse('{"title":"Gender Performativity","description":"","frontmatter":{"public":"true","slug":"gender-performativity","title":"Gender Performativity","prev":false,"next":false},"headers":[],"relativePath":"garden/gender-performativity/index.md","filePath":"garden/gender-performativity/index.md"}'),u={name:"garden/gender-performativity/index.md"},b=Object.assign(u,{setup(h){const t=n();return(_,c)=>(d(),i("div",null,[l,e("p",null,[s("2 words, ~0 minute read. "),e("span",{innerHTML:r(a)[`site/${r(t).page.value.relativePath}`]},null,8,m)]),p]))}});export{y as __pageData,b as default}; +import{d as a}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as i,Q as e,K as s,u as r,ag as o,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Gender Performativity",-1),m=["innerHTML"],p=o('
Referenced by:ObjectivityPersonality

A Gender theory by Judith Butler, as described in Gender Trouble. Butler argues that we observe gender norms performed by others and reproduce them. In this way, gender is a force that acts upon us. Philosophy Tube describes this theory in more detail in I read the most misunderstood philosopher in the world

',3),y=JSON.parse('{"title":"Gender Performativity","description":"","frontmatter":{"public":"true","slug":"gender-performativity","title":"Gender Performativity","prev":false,"next":false},"headers":[],"relativePath":"garden/gender-performativity/index.md","filePath":"garden/gender-performativity/index.md"}'),u={name:"garden/gender-performativity/index.md"},b=Object.assign(u,{setup(h){const t=n();return(_,c)=>(d(),i("div",null,[l,e("p",null,[s("2 words, ~0 minute read. "),e("span",{innerHTML:r(a)[`site/${r(t).page.value.relativePath}`]},null,8,m)]),p]))}});export{y as __pageData,b as default}; diff --git a/assets/garden_gender-performativity_index.md.CnW1xA_a.lean.js b/assets/garden_gender-performativity_index.md.s4FTNt-A.lean.js similarity index 92% rename from assets/garden_gender-performativity_index.md.CnW1xA_a.lean.js rename to assets/garden_gender-performativity_index.md.s4FTNt-A.lean.js index 8b9034b36..023109703 100644 --- a/assets/garden_gender-performativity_index.md.CnW1xA_a.lean.js +++ b/assets/garden_gender-performativity_index.md.s4FTNt-A.lean.js @@ -1 +1 @@ -import{d as a}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as i,Q as e,K as s,u as r,ag as o,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Gender Performativity",-1),m=["innerHTML"],p=o("",3),y=JSON.parse('{"title":"Gender Performativity","description":"","frontmatter":{"public":"true","slug":"gender-performativity","title":"Gender Performativity","prev":false,"next":false},"headers":[],"relativePath":"garden/gender-performativity/index.md","filePath":"garden/gender-performativity/index.md"}'),u={name:"garden/gender-performativity/index.md"},b=Object.assign(u,{setup(h){const t=n();return(_,c)=>(d(),i("div",null,[l,e("p",null,[s("2 words, ~0 minute read. "),e("span",{innerHTML:r(a)[`site/${r(t).page.value.relativePath}`]},null,8,m)]),p]))}});export{y as __pageData,b as default}; +import{d as a}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as i,Q as e,K as s,u as r,ag as o,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Gender Performativity",-1),m=["innerHTML"],p=o("",3),y=JSON.parse('{"title":"Gender Performativity","description":"","frontmatter":{"public":"true","slug":"gender-performativity","title":"Gender Performativity","prev":false,"next":false},"headers":[],"relativePath":"garden/gender-performativity/index.md","filePath":"garden/gender-performativity/index.md"}'),u={name:"garden/gender-performativity/index.md"},b=Object.assign(u,{setup(h){const t=n();return(_,c)=>(d(),i("div",null,[l,e("p",null,[s("2 words, ~0 minute read. "),e("span",{innerHTML:r(a)[`site/${r(t).page.value.relativePath}`]},null,8,m)]),p]))}});export{y as __pageData,b as default}; diff --git a/assets/garden_gender_index.md.DZdlSD4a.js b/assets/garden_gender_index.md.DoQhDjKl.js similarity index 98% rename from assets/garden_gender_index.md.DZdlSD4a.js rename to assets/garden_gender_index.md.DoQhDjKl.js index 6846bb9bf..601e228d4 100644 --- a/assets/garden_gender_index.md.DZdlSD4a.js +++ b/assets/garden_gender_index.md.DoQhDjKl.js @@ -1 +1 @@ -import{d as o}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as n,Q as e,K as i,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Gender",-1),d=["innerHTML"],h=r('
Referenced by:Gender PerformativitySocial ConstructsTrans athletes in sports

Gender is a tricky subject, and there are many conflicting frameworks that have been proposed for defining gender and measuring its impact, and other such aspects of it. Judith Butler, for example, controversially describes gender as a performance); We observe how people act, what they seem to enjoy, and what roles they fill in society based on their gender, and then we (often subconsciously) perform similarly, perpetuating the cycle. That makes gender a Social Construct.

Gender is a very sensitive topic, especially as people's identities are constantly under attack within the west. I'd like to make it explicitly clear I support any and all gender identities, and re-affirm that just because something is a construct does not mean its bad or useless. It just means society has decided to give it meaning, and I think gender will be very meaningful to people for a very very long time. These frameworks used for analyzing it and determining its utility are some nice philosophical exercises, but above all it should be clear any political goal should be to eliminate discrimination against marginalized peoples.

There are some people who believe gender is an exclusively unuseful and negative social construct and should be entirely abolished, and see this act as a requirement for liberating queer people and women. You'll see plenty of people push back on this idea, saying they like their genders, though, and sometimes even trying to co-opt "gender abolitionism" as referring to only abolishing gender roles rather than gender itself as a construct. It's seen as a stance that essentially invalidates the motivation behind so many people going through great efforts to transition from one gender to another. An even more pessimistic stance on gender abolition sees it as a return to biological sex, even further erasing the plights of trans people. However, I think as society progresses towards post-scarcity, a lot of constructs will over time see a natural end as they become less useful, and I do think we'll eventually see a post-gender society where everyone is just "themselves", and the realm of self expression is massively expanded, but no longer sees a need for gender as a construct.

Alright, with that established it's time for another controversial take: Biological sex is also a social construct. Sex is a term used to refer to a collection of underlying natural properties from which sex determining genes one has, which sex chromosomes are present, how much of each sex hormone gets produced, which genitals one has, which hormones get processed, what happens during puberty, and so on. Besides the fact there's plenty of people who don't have every single of the above properties cleanly fit into the same bucket, the fact we choose to imbue those properties with meaning makes them a construct as well, and in fact we imbued them with so much meaning we built our entire society around it. Sure, we created gender as a way of abstracting the roles in the society from the natural properties, but ultimately they're both just as arbitrary distinctions we collectively chose to make. And yet, positioning gender as the social construct and biological sex as the "objective" underlying property, you open the door to essentially continue discriminating against a significant amount of the population, using "truth" and "science" to justify their position.

To be clear, I'm not saying biology doesn't matter (and neither does anyone else who argues sex is also a social construct). Obviously someone with a uterus is going to have different medical risks and opportunities than someone without. But using the presence of that uterus to socially and culturally discriminate against someone is not okay. In fact, society placing importance on the number of years spent at a job is a form of discriminating against people who choose to take time off work to be a parent, even if their actual ability to perform that job is not impacted at all. This impacts both career trajectory as well as making it more difficult to even get some jobs in the first place. I recommend Biological sex is a social construct for further exploration into this concept.

Identity, Gender, and VRChat explores how VRChat has enabled people to explore their gender expression and other parts of their identity in a low risk and very accepting environment. I haven't used VRChat myself, but that sounds like an amazing resource for people to be able to use, and honestly makes me hope socializing in VR becomes an increasingly normalized and accessible activity.

',8),b=JSON.parse('{"title":"Gender","description":"","frontmatter":{"alias":"Sex","public":"true","slug":"gender","title":"Gender","prev":false,"next":false},"headers":[],"relativePath":"garden/gender/index.md","filePath":"garden/gender/index.md"}'),u={name:"garden/gender/index.md"},v=Object.assign(u,{setup(p){const a=s();return(m,g)=>(l(),n("div",null,[c,e("p",null,[i("741 words, ~4 minute read. "),e("span",{innerHTML:t(o)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),h]))}});export{b as __pageData,v as default}; +import{d as o}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as n,Q as e,K as i,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Gender",-1),d=["innerHTML"],h=r('
Referenced by:Gender PerformativitySocial ConstructsTrans athletes in sports

Gender is a tricky subject, and there are many conflicting frameworks that have been proposed for defining gender and measuring its impact, and other such aspects of it. Judith Butler, for example, controversially describes gender as a performance); We observe how people act, what they seem to enjoy, and what roles they fill in society based on their gender, and then we (often subconsciously) perform similarly, perpetuating the cycle. That makes gender a Social Construct.

Gender is a very sensitive topic, especially as people's identities are constantly under attack within the west. I'd like to make it explicitly clear I support any and all gender identities, and re-affirm that just because something is a construct does not mean its bad or useless. It just means society has decided to give it meaning, and I think gender will be very meaningful to people for a very very long time. These frameworks used for analyzing it and determining its utility are some nice philosophical exercises, but above all it should be clear any political goal should be to eliminate discrimination against marginalized peoples.

There are some people who believe gender is an exclusively unuseful and negative social construct and should be entirely abolished, and see this act as a requirement for liberating queer people and women. You'll see plenty of people push back on this idea, saying they like their genders, though, and sometimes even trying to co-opt "gender abolitionism" as referring to only abolishing gender roles rather than gender itself as a construct. It's seen as a stance that essentially invalidates the motivation behind so many people going through great efforts to transition from one gender to another. An even more pessimistic stance on gender abolition sees it as a return to biological sex, even further erasing the plights of trans people. However, I think as society progresses towards post-scarcity, a lot of constructs will over time see a natural end as they become less useful, and I do think we'll eventually see a post-gender society where everyone is just "themselves", and the realm of self expression is massively expanded, but no longer sees a need for gender as a construct.

Alright, with that established it's time for another controversial take: Biological sex is also a social construct. Sex is a term used to refer to a collection of underlying natural properties from which sex determining genes one has, which sex chromosomes are present, how much of each sex hormone gets produced, which genitals one has, which hormones get processed, what happens during puberty, and so on. Besides the fact there's plenty of people who don't have every single of the above properties cleanly fit into the same bucket, the fact we choose to imbue those properties with meaning makes them a construct as well, and in fact we imbued them with so much meaning we built our entire society around it. Sure, we created gender as a way of abstracting the roles in the society from the natural properties, but ultimately they're both just as arbitrary distinctions we collectively chose to make. And yet, positioning gender as the social construct and biological sex as the "objective" underlying property, you open the door to essentially continue discriminating against a significant amount of the population, using "truth" and "science" to justify their position.

To be clear, I'm not saying biology doesn't matter (and neither does anyone else who argues sex is also a social construct). Obviously someone with a uterus is going to have different medical risks and opportunities than someone without. But using the presence of that uterus to socially and culturally discriminate against someone is not okay. In fact, society placing importance on the number of years spent at a job is a form of discriminating against people who choose to take time off work to be a parent, even if their actual ability to perform that job is not impacted at all. This impacts both career trajectory as well as making it more difficult to even get some jobs in the first place. I recommend Biological sex is a social construct for further exploration into this concept.

Identity, Gender, and VRChat explores how VRChat has enabled people to explore their gender expression and other parts of their identity in a low risk and very accepting environment. I haven't used VRChat myself, but that sounds like an amazing resource for people to be able to use, and honestly makes me hope socializing in VR becomes an increasingly normalized and accessible activity.

',8),b=JSON.parse('{"title":"Gender","description":"","frontmatter":{"alias":"Sex","public":"true","slug":"gender","title":"Gender","prev":false,"next":false},"headers":[],"relativePath":"garden/gender/index.md","filePath":"garden/gender/index.md"}'),u={name:"garden/gender/index.md"},v=Object.assign(u,{setup(p){const a=s();return(m,g)=>(l(),n("div",null,[c,e("p",null,[i("741 words, ~4 minute read. "),e("span",{innerHTML:t(o)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),h]))}});export{b as __pageData,v as default}; diff --git a/assets/garden_gender_index.md.DZdlSD4a.lean.js b/assets/garden_gender_index.md.DoQhDjKl.lean.js similarity index 91% rename from assets/garden_gender_index.md.DZdlSD4a.lean.js rename to assets/garden_gender_index.md.DoQhDjKl.lean.js index 9c10bfa1d..e9ef7a90c 100644 --- a/assets/garden_gender_index.md.DZdlSD4a.lean.js +++ b/assets/garden_gender_index.md.DoQhDjKl.lean.js @@ -1 +1 @@ -import{d as o}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as n,Q as e,K as i,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Gender",-1),d=["innerHTML"],h=r("",8),b=JSON.parse('{"title":"Gender","description":"","frontmatter":{"alias":"Sex","public":"true","slug":"gender","title":"Gender","prev":false,"next":false},"headers":[],"relativePath":"garden/gender/index.md","filePath":"garden/gender/index.md"}'),u={name:"garden/gender/index.md"},v=Object.assign(u,{setup(p){const a=s();return(m,g)=>(l(),n("div",null,[c,e("p",null,[i("741 words, ~4 minute read. "),e("span",{innerHTML:t(o)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),h]))}});export{b as __pageData,v as default}; +import{d as o}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as n,Q as e,K as i,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Gender",-1),d=["innerHTML"],h=r("",8),b=JSON.parse('{"title":"Gender","description":"","frontmatter":{"alias":"Sex","public":"true","slug":"gender","title":"Gender","prev":false,"next":false},"headers":[],"relativePath":"garden/gender/index.md","filePath":"garden/gender/index.md"}'),u={name:"garden/gender/index.md"},v=Object.assign(u,{setup(p){const a=s();return(m,g)=>(l(),n("div",null,[c,e("p",null,[i("741 words, ~4 minute read. "),e("span",{innerHTML:t(o)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),h]))}});export{b as __pageData,v as default}; diff --git a/assets/garden_gerrymandering_index.md.CX2OFSlv.js b/assets/garden_gerrymandering_index.md.CsB_YWSB.js similarity index 99% rename from assets/garden_gerrymandering_index.md.CX2OFSlv.js rename to assets/garden_gerrymandering_index.md.CsB_YWSB.js index a1f2d0552..02fffc365 100644 --- a/assets/garden_gerrymandering_index.md.CX2OFSlv.js +++ b/assets/garden_gerrymandering_index.md.CsB_YWSB.js @@ -1 +1 @@ -import{M as i,q as o,Q as e,K as t,u as r,ar as s,as as n,ag as l,p as c}from"./chunks/framework.Sr2_9k8k.js";import{d as h}from"./chunks/git.data.D-Ga3RhB.js";const d=e("h1",{class:"p-name"},"Gerrymandering",-1),p=["innerHTML"],m=e("hr",null,null,-1),u=e("p",null,[t("Gerrymandering, or the deliberate outlining of voting districts in order to consolidate or spread out voters who you expect to vote similarly to each other, is typically portrayed as an unambiguously unfair thing to do. And I (typically) agree! But there are some interesting caveats that illustrate how illusory our concept of fairness really is, that demonstrate it is in fact a "),e("a",{href:"/garden/social-constructs/"},"Social Construct"),t(". For example, Louisiana's most recent redistricting (in 2024) stirred up controversy for a new district, district 6, being drawn with very weird borders, specifically to ensure it has a majority of black voters who were previously more spread out across the districts. This is classic gerrymandering that makes it so that voting bloc determines the result of that district and the one already existing majority black district, but has nominal impact on any of the other 4 districts. But this process is actually being argued to be more fair to black voters, because previous congressional maps, despite appearing more fair, were not very proportional to race by only having 1 majority black district versus 5 majority white districts. This is the racial composition of Louisiana based on census data from 2017 to 2021, and the new congressional map highlighting the 2 districts that are majority black:")],-1),g=e("div",{class:"img-container"},[e("img",{src:s,title:"louisiana-population-by-race.jpeg"})],-1),y=e("div",{class:"img-container"},[e("img",{src:n,title:"LA-New-Cong-Map-1024x885.webp"})],-1),f=l('

Having 2 districts means black voters are represented by 1/3 of the districts, which is remarkably proportional, considering they make up 32% of the population. In this way, the gerrymandering is being employed to make the district representation more proportional by race, which groups like the NAACP argue makes them more fair. I agree with their assessment and think this will make Louisiana much more fair, and that's awesome. Naturally, it is being sued for its obvious gerrymandering however, with arguments that it is making the election less fair, under the definition that gerrymandering is intrinsically unfair.

Both sides of the argument are dealing with conflicting definitions of fairness. Determining it based on how close to square each district ends up is just as arbitrary as making them proportional by race. They could have been proportional by age or party or hobby. And in any case, 6 representatives means the proportions are going to be very crude proportions in anyways - the racial composition showed no other races reached the ~1/6 of a population required to be given a single representative, so is it "fair" that they don't get any representative of their own? And is it even fair to be treating racial demographics as a monolithic voting blocs in the first place? Sure those two districts are gerrymandered to be majority black, but what if they're also all the black voters that voted a specific way, and the ones who voted another way are the ones still spread out across the majority white districts?

These are not new insights, and in fact many argue that congressional districts should just use proportional representation directly, which would allow for larger districts with multiple representatives based on votes (such as a ranked choice vote, where you keep picking the most voted person, redistribute their votes to their next pick, and continue until all representatives picked), regardless of demographics or how anyone decided to draw up lines on a map... Except even then, what if the larger districts are still gerrymandered? What if the state itself is gerrymandered? Louisiana being composed of 32% black voters is "packed" considering the US as a whole only has a 12% black population. And unless we increase the number of representatives, there's likely still going to be demographics and political dispositions that lack even a single representative. But maybe some would argue below that 1 representative threshold, those demographics and political views aren't significant enough to warrant a material impact on how the area is run?

I've been mentioning race a lot here, but I think it's important to understand why that demographic specifically is considered so important to account for here. America is and has been a racist country for a long time, with many issues present in the system itself, and therefore our social constructs as well. Black people have been regularly under-represented in our government and suffered greatly for it. I've been making the case that proportionality by race is a reasonable metric for fairness, but to be honest there's quite a strong case that, due to historical oppression, black people may deserve to be over-represented in order to help them regain equal footing in our society. To help correct the racist parts very much still present in our laws and processes, which may be hard to do if a minority of our representatives are chosen by black people. This adds a whole new facet to our discussion on fairness that I'm only briefly touching on here, but even proportionality may not be considered "fair", due to its ambivalence to historical context.

My personal stance on what would be most fair is actually that representation is intrinsically an inaccurate abstraction of the people's political will. I think the closer we get to having individuals voting directly on the issues the better (see Direct Democracy ), and beyond that I'd ideally prefer a system where policies are workshopped and ideated upon until they can achieve a near unanimous vote before being implemented (see Consensus Democracy ). But hopefully all of this goes to show how complex fairness is, and how there is no "objectively" definition of fairness. Therefore, arguments should not center on appeals to "fairness" like its some objective or authoritative measure. You must be able to justify why your policy improves things in material. And to clarify, I do support the new congressional map that makes two majority black voting districts - I'm all for harm reduction, and that map is the least we can do in trying to make the system more fair, by most reasonable definitions of fairness.

',5),x=JSON.parse('{"title":"Gerrymandering","description":"","frontmatter":{"public":"true","slug":"gerrymandering","title":"Gerrymandering","prev":false,"next":false},"headers":[],"relativePath":"garden/gerrymandering/index.md","filePath":"garden/gerrymandering/index.md"}'),b={name:"garden/gerrymandering/index.md"},T=Object.assign(b,{setup(w){const a=i();return(v,k)=>(c(),o("div",null,[d,e("p",null,[t("926 words, ~5 minute read. "),e("span",{innerHTML:r(h)[`site/${r(a).page.value.relativePath}`]},null,8,p)]),m,u,g,t(" Source: [Neilsberg](https://www.neilsberg.com/insights/topic/louisiana-population/) "),y,t(" Source: [Democracy Docket](https://www.democracydocket.com/news-alerts/new-louisiana-congressional-map-with-two-majority-black-districts-heads-to-governor/) "),f]))}});export{x as __pageData,T as default}; +import{M as i,q as o,Q as e,K as t,u as r,ar as s,as as n,ag as l,p as c}from"./chunks/framework.Sr2_9k8k.js";import{d as h}from"./chunks/git.data.BcrWSzMU.js";const d=e("h1",{class:"p-name"},"Gerrymandering",-1),p=["innerHTML"],m=e("hr",null,null,-1),u=e("p",null,[t("Gerrymandering, or the deliberate outlining of voting districts in order to consolidate or spread out voters who you expect to vote similarly to each other, is typically portrayed as an unambiguously unfair thing to do. And I (typically) agree! But there are some interesting caveats that illustrate how illusory our concept of fairness really is, that demonstrate it is in fact a "),e("a",{href:"/garden/social-constructs/"},"Social Construct"),t(". For example, Louisiana's most recent redistricting (in 2024) stirred up controversy for a new district, district 6, being drawn with very weird borders, specifically to ensure it has a majority of black voters who were previously more spread out across the districts. This is classic gerrymandering that makes it so that voting bloc determines the result of that district and the one already existing majority black district, but has nominal impact on any of the other 4 districts. But this process is actually being argued to be more fair to black voters, because previous congressional maps, despite appearing more fair, were not very proportional to race by only having 1 majority black district versus 5 majority white districts. This is the racial composition of Louisiana based on census data from 2017 to 2021, and the new congressional map highlighting the 2 districts that are majority black:")],-1),g=e("div",{class:"img-container"},[e("img",{src:s,title:"louisiana-population-by-race.jpeg"})],-1),y=e("div",{class:"img-container"},[e("img",{src:n,title:"LA-New-Cong-Map-1024x885.webp"})],-1),f=l('

Having 2 districts means black voters are represented by 1/3 of the districts, which is remarkably proportional, considering they make up 32% of the population. In this way, the gerrymandering is being employed to make the district representation more proportional by race, which groups like the NAACP argue makes them more fair. I agree with their assessment and think this will make Louisiana much more fair, and that's awesome. Naturally, it is being sued for its obvious gerrymandering however, with arguments that it is making the election less fair, under the definition that gerrymandering is intrinsically unfair.

Both sides of the argument are dealing with conflicting definitions of fairness. Determining it based on how close to square each district ends up is just as arbitrary as making them proportional by race. They could have been proportional by age or party or hobby. And in any case, 6 representatives means the proportions are going to be very crude proportions in anyways - the racial composition showed no other races reached the ~1/6 of a population required to be given a single representative, so is it "fair" that they don't get any representative of their own? And is it even fair to be treating racial demographics as a monolithic voting blocs in the first place? Sure those two districts are gerrymandered to be majority black, but what if they're also all the black voters that voted a specific way, and the ones who voted another way are the ones still spread out across the majority white districts?

These are not new insights, and in fact many argue that congressional districts should just use proportional representation directly, which would allow for larger districts with multiple representatives based on votes (such as a ranked choice vote, where you keep picking the most voted person, redistribute their votes to their next pick, and continue until all representatives picked), regardless of demographics or how anyone decided to draw up lines on a map... Except even then, what if the larger districts are still gerrymandered? What if the state itself is gerrymandered? Louisiana being composed of 32% black voters is "packed" considering the US as a whole only has a 12% black population. And unless we increase the number of representatives, there's likely still going to be demographics and political dispositions that lack even a single representative. But maybe some would argue below that 1 representative threshold, those demographics and political views aren't significant enough to warrant a material impact on how the area is run?

I've been mentioning race a lot here, but I think it's important to understand why that demographic specifically is considered so important to account for here. America is and has been a racist country for a long time, with many issues present in the system itself, and therefore our social constructs as well. Black people have been regularly under-represented in our government and suffered greatly for it. I've been making the case that proportionality by race is a reasonable metric for fairness, but to be honest there's quite a strong case that, due to historical oppression, black people may deserve to be over-represented in order to help them regain equal footing in our society. To help correct the racist parts very much still present in our laws and processes, which may be hard to do if a minority of our representatives are chosen by black people. This adds a whole new facet to our discussion on fairness that I'm only briefly touching on here, but even proportionality may not be considered "fair", due to its ambivalence to historical context.

My personal stance on what would be most fair is actually that representation is intrinsically an inaccurate abstraction of the people's political will. I think the closer we get to having individuals voting directly on the issues the better (see Direct Democracy ), and beyond that I'd ideally prefer a system where policies are workshopped and ideated upon until they can achieve a near unanimous vote before being implemented (see Consensus Democracy ). But hopefully all of this goes to show how complex fairness is, and how there is no "objectively" definition of fairness. Therefore, arguments should not center on appeals to "fairness" like its some objective or authoritative measure. You must be able to justify why your policy improves things in material. And to clarify, I do support the new congressional map that makes two majority black voting districts - I'm all for harm reduction, and that map is the least we can do in trying to make the system more fair, by most reasonable definitions of fairness.

',5),x=JSON.parse('{"title":"Gerrymandering","description":"","frontmatter":{"public":"true","slug":"gerrymandering","title":"Gerrymandering","prev":false,"next":false},"headers":[],"relativePath":"garden/gerrymandering/index.md","filePath":"garden/gerrymandering/index.md"}'),b={name:"garden/gerrymandering/index.md"},T=Object.assign(b,{setup(w){const a=i();return(v,k)=>(c(),o("div",null,[d,e("p",null,[t("926 words, ~5 minute read. "),e("span",{innerHTML:r(h)[`site/${r(a).page.value.relativePath}`]},null,8,p)]),m,u,g,t(" Source: [Neilsberg](https://www.neilsberg.com/insights/topic/louisiana-population/) "),y,t(" Source: [Democracy Docket](https://www.democracydocket.com/news-alerts/new-louisiana-congressional-map-with-two-majority-black-districts-heads-to-governor/) "),f]))}});export{x as __pageData,T as default}; diff --git a/assets/garden_gerrymandering_index.md.CX2OFSlv.lean.js b/assets/garden_gerrymandering_index.md.CsB_YWSB.lean.js similarity index 97% rename from assets/garden_gerrymandering_index.md.CX2OFSlv.lean.js rename to assets/garden_gerrymandering_index.md.CsB_YWSB.lean.js index a625d22c5..506b67b19 100644 --- a/assets/garden_gerrymandering_index.md.CX2OFSlv.lean.js +++ b/assets/garden_gerrymandering_index.md.CsB_YWSB.lean.js @@ -1 +1 @@ -import{M as i,q as o,Q as e,K as t,u as r,ar as s,as as n,ag as l,p as c}from"./chunks/framework.Sr2_9k8k.js";import{d as h}from"./chunks/git.data.D-Ga3RhB.js";const d=e("h1",{class:"p-name"},"Gerrymandering",-1),p=["innerHTML"],m=e("hr",null,null,-1),u=e("p",null,[t("Gerrymandering, or the deliberate outlining of voting districts in order to consolidate or spread out voters who you expect to vote similarly to each other, is typically portrayed as an unambiguously unfair thing to do. And I (typically) agree! But there are some interesting caveats that illustrate how illusory our concept of fairness really is, that demonstrate it is in fact a "),e("a",{href:"/garden/social-constructs/"},"Social Construct"),t(". For example, Louisiana's most recent redistricting (in 2024) stirred up controversy for a new district, district 6, being drawn with very weird borders, specifically to ensure it has a majority of black voters who were previously more spread out across the districts. This is classic gerrymandering that makes it so that voting bloc determines the result of that district and the one already existing majority black district, but has nominal impact on any of the other 4 districts. But this process is actually being argued to be more fair to black voters, because previous congressional maps, despite appearing more fair, were not very proportional to race by only having 1 majority black district versus 5 majority white districts. This is the racial composition of Louisiana based on census data from 2017 to 2021, and the new congressional map highlighting the 2 districts that are majority black:")],-1),g=e("div",{class:"img-container"},[e("img",{src:s,title:"louisiana-population-by-race.jpeg"})],-1),y=e("div",{class:"img-container"},[e("img",{src:n,title:"LA-New-Cong-Map-1024x885.webp"})],-1),f=l("",5),x=JSON.parse('{"title":"Gerrymandering","description":"","frontmatter":{"public":"true","slug":"gerrymandering","title":"Gerrymandering","prev":false,"next":false},"headers":[],"relativePath":"garden/gerrymandering/index.md","filePath":"garden/gerrymandering/index.md"}'),b={name:"garden/gerrymandering/index.md"},T=Object.assign(b,{setup(w){const a=i();return(v,k)=>(c(),o("div",null,[d,e("p",null,[t("926 words, ~5 minute read. "),e("span",{innerHTML:r(h)[`site/${r(a).page.value.relativePath}`]},null,8,p)]),m,u,g,t(" Source: [Neilsberg](https://www.neilsberg.com/insights/topic/louisiana-population/) "),y,t(" Source: [Democracy Docket](https://www.democracydocket.com/news-alerts/new-louisiana-congressional-map-with-two-majority-black-districts-heads-to-governor/) "),f]))}});export{x as __pageData,T as default}; +import{M as i,q as o,Q as e,K as t,u as r,ar as s,as as n,ag as l,p as c}from"./chunks/framework.Sr2_9k8k.js";import{d as h}from"./chunks/git.data.BcrWSzMU.js";const d=e("h1",{class:"p-name"},"Gerrymandering",-1),p=["innerHTML"],m=e("hr",null,null,-1),u=e("p",null,[t("Gerrymandering, or the deliberate outlining of voting districts in order to consolidate or spread out voters who you expect to vote similarly to each other, is typically portrayed as an unambiguously unfair thing to do. And I (typically) agree! But there are some interesting caveats that illustrate how illusory our concept of fairness really is, that demonstrate it is in fact a "),e("a",{href:"/garden/social-constructs/"},"Social Construct"),t(". For example, Louisiana's most recent redistricting (in 2024) stirred up controversy for a new district, district 6, being drawn with very weird borders, specifically to ensure it has a majority of black voters who were previously more spread out across the districts. This is classic gerrymandering that makes it so that voting bloc determines the result of that district and the one already existing majority black district, but has nominal impact on any of the other 4 districts. But this process is actually being argued to be more fair to black voters, because previous congressional maps, despite appearing more fair, were not very proportional to race by only having 1 majority black district versus 5 majority white districts. This is the racial composition of Louisiana based on census data from 2017 to 2021, and the new congressional map highlighting the 2 districts that are majority black:")],-1),g=e("div",{class:"img-container"},[e("img",{src:s,title:"louisiana-population-by-race.jpeg"})],-1),y=e("div",{class:"img-container"},[e("img",{src:n,title:"LA-New-Cong-Map-1024x885.webp"})],-1),f=l("",5),x=JSON.parse('{"title":"Gerrymandering","description":"","frontmatter":{"public":"true","slug":"gerrymandering","title":"Gerrymandering","prev":false,"next":false},"headers":[],"relativePath":"garden/gerrymandering/index.md","filePath":"garden/gerrymandering/index.md"}'),b={name:"garden/gerrymandering/index.md"},T=Object.assign(b,{setup(w){const a=i();return(v,k)=>(c(),o("div",null,[d,e("p",null,[t("926 words, ~5 minute read. "),e("span",{innerHTML:r(h)[`site/${r(a).page.value.relativePath}`]},null,8,p)]),m,u,g,t(" Source: [Neilsberg](https://www.neilsberg.com/insights/topic/louisiana-population/) "),y,t(" Source: [Democracy Docket](https://www.democracydocket.com/news-alerts/new-louisiana-congressional-map-with-two-majority-black-districts-heads-to-governor/) "),f]))}});export{x as __pageData,T as default}; diff --git a/assets/garden_guide-to-incrementals_appeal-to-developers_index.md.CkuW5uER.js b/assets/garden_guide-to-incrementals_appeal-to-developers_index.md.DlM-Yrns.js similarity index 98% rename from assets/garden_guide-to-incrementals_appeal-to-developers_index.md.CkuW5uER.js rename to assets/garden_guide-to-incrementals_appeal-to-developers_index.md.DlM-Yrns.js index 31fc6f028..6ca22cd2f 100644 --- a/assets/garden_guide-to-incrementals_appeal-to-developers_index.md.CkuW5uER.js +++ b/assets/garden_guide-to-incrementals_appeal-to-developers_index.md.DlM-Yrns.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as i,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const m=e("h1",{class:"p-name"},"Guide to Incrementals/Appeal to Developers",-1),d=["innerHTML"],c=s('
Referenced by:Incremental SocialKronos

There are a lot of developers in the incremental games community - the genre seems to draw them in, and convert a lot of players into developers. Let's explore the reasons why this genre appeals to developers.

Incrementals are Easy to Make

Compared to other genres, incrementals have quite low expectations. You don't need to make fancy art, or music, or lay things out nicely. If you can make a button and learn the few lines of code necessary to make a number go up, you can make an incremental. This low threshold makes the genre perfect for those who are actively learning to code and haven't developed any gamedev-related skills yet.

Additionally, unlike other genres incrementals are uniquely easy to implement in a normal web page - no need to worry about rendering sprites, moving them around, implementing physics, etc. New developers can just use HTML to add a button, and the game is now available in your browser. You don't need to choose an engine, have admin privileges, or hell for the dedicated you don't even need a computer - there are tools for web development that run in the browser itself, so you can technically use your phone if that's all you have.

Javascript is a perfectly viable language for making web games, whereas other genres are typically going to require using other more difficult languages to learn. There are countless javascript tutorials that start from 0 knowledge of programming, making it incredibly accessible to beginners.

Players are Easy to Find

Once you've finished your game and uploaded it on github pages or itch or just copied the link if you're using glitch or replit (all of which are easy to do), anyone can now play the game in their browser. This low barrier to entry has shown tremendous success in getting completely unknown developers to have thousands of plays.

The incremental games community, which mostly centers around r/incremental_games, is always looking for new games and tends to flood any new ones posted with initial players.

Having your games be played can be incredibly motivating, and the community makes it quite clear that you can expect players to play your game. These communities - both for incremental games in general as well as game-specific communities - tend to be very developer friendly as well. A lot of the developers know each other, and welcome new developers with open arms, often with dedicated channels for programming help and discussions.

Monetization

I'd like to clarify that everything I've said above mainly applies to web-based incrementals. Incremental games are also incredibly popular on mobile, but with a much different culture and community. Many mobile gamers will still participate in the web-focused community for the culture. This web-focused community has a culture that has been criticized for being "anti-monetization". Ads, IAPs, and similar forms of monetization are often criticized, mainly due to the abundance of completely non-monetized games available from hobbyist developers. There are exceptions, like paid games often being considered fine, like Increlution or Stuck in Time, or donation ware games like kittens game, but even popular games that have IAP see some level of regular criticism, like NGU Idle, Idle Skilling, or Idle Pins. A large part of this can be explained by the community being hyper-aware of the addictive) nature of this genre and its susceptibility to exploiting players.

On mobile, however, monetization is the norm and expected. If an incremental game is available on mobile, it almost certainly will be monetized, and mobile players are aware and accepting of that. Mobile incremental games, due to their addictive nature, tend to make a lot of money. It's very lucrative, and therefore these games are quite abundant on mobile storefronts.

',14),b=JSON.parse('{"title":"Guide to Incrementals/Appeal to Developers","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/appeal-to-developers","title":"Guide to Incrementals/Appeal to Developers","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/appeal-to-developers/index.md","filePath":"garden/guide-to-incrementals/appeal-to-developers/index.md"}'),p={name:"garden/guide-to-incrementals/appeal-to-developers/index.md"},v=Object.assign(p,{setup(h){const t=o();return(u,g)=>(l(),i("div",null,[m,e("p",null,[r("636 words, ~3 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),c]))}});export{b as __pageData,v as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as i,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const m=e("h1",{class:"p-name"},"Guide to Incrementals/Appeal to Developers",-1),d=["innerHTML"],c=s('
Referenced by:Incremental SocialKronos

There are a lot of developers in the incremental games community - the genre seems to draw them in, and convert a lot of players into developers. Let's explore the reasons why this genre appeals to developers.

Incrementals are Easy to Make

Compared to other genres, incrementals have quite low expectations. You don't need to make fancy art, or music, or lay things out nicely. If you can make a button and learn the few lines of code necessary to make a number go up, you can make an incremental. This low threshold makes the genre perfect for those who are actively learning to code and haven't developed any gamedev-related skills yet.

Additionally, unlike other genres incrementals are uniquely easy to implement in a normal web page - no need to worry about rendering sprites, moving them around, implementing physics, etc. New developers can just use HTML to add a button, and the game is now available in your browser. You don't need to choose an engine, have admin privileges, or hell for the dedicated you don't even need a computer - there are tools for web development that run in the browser itself, so you can technically use your phone if that's all you have.

Javascript is a perfectly viable language for making web games, whereas other genres are typically going to require using other more difficult languages to learn. There are countless javascript tutorials that start from 0 knowledge of programming, making it incredibly accessible to beginners.

Players are Easy to Find

Once you've finished your game and uploaded it on github pages or itch or just copied the link if you're using glitch or replit (all of which are easy to do), anyone can now play the game in their browser. This low barrier to entry has shown tremendous success in getting completely unknown developers to have thousands of plays.

The incremental games community, which mostly centers around r/incremental_games, is always looking for new games and tends to flood any new ones posted with initial players.

Having your games be played can be incredibly motivating, and the community makes it quite clear that you can expect players to play your game. These communities - both for incremental games in general as well as game-specific communities - tend to be very developer friendly as well. A lot of the developers know each other, and welcome new developers with open arms, often with dedicated channels for programming help and discussions.

Monetization

I'd like to clarify that everything I've said above mainly applies to web-based incrementals. Incremental games are also incredibly popular on mobile, but with a much different culture and community. Many mobile gamers will still participate in the web-focused community for the culture. This web-focused community has a culture that has been criticized for being "anti-monetization". Ads, IAPs, and similar forms of monetization are often criticized, mainly due to the abundance of completely non-monetized games available from hobbyist developers. There are exceptions, like paid games often being considered fine, like Increlution or Stuck in Time, or donation ware games like kittens game, but even popular games that have IAP see some level of regular criticism, like NGU Idle, Idle Skilling, or Idle Pins. A large part of this can be explained by the community being hyper-aware of the addictive) nature of this genre and its susceptibility to exploiting players.

On mobile, however, monetization is the norm and expected. If an incremental game is available on mobile, it almost certainly will be monetized, and mobile players are aware and accepting of that. Mobile incremental games, due to their addictive nature, tend to make a lot of money. It's very lucrative, and therefore these games are quite abundant on mobile storefronts.

',14),b=JSON.parse('{"title":"Guide to Incrementals/Appeal to Developers","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/appeal-to-developers","title":"Guide to Incrementals/Appeal to Developers","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/appeal-to-developers/index.md","filePath":"garden/guide-to-incrementals/appeal-to-developers/index.md"}'),p={name:"garden/guide-to-incrementals/appeal-to-developers/index.md"},v=Object.assign(p,{setup(h){const t=o();return(u,g)=>(l(),i("div",null,[m,e("p",null,[r("636 words, ~3 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),c]))}});export{b as __pageData,v as default}; diff --git a/assets/garden_guide-to-incrementals_appeal-to-developers_index.md.CkuW5uER.lean.js b/assets/garden_guide-to-incrementals_appeal-to-developers_index.md.DlM-Yrns.lean.js similarity index 93% rename from assets/garden_guide-to-incrementals_appeal-to-developers_index.md.CkuW5uER.lean.js rename to assets/garden_guide-to-incrementals_appeal-to-developers_index.md.DlM-Yrns.lean.js index ecbf8e125..b7be0cee4 100644 --- a/assets/garden_guide-to-incrementals_appeal-to-developers_index.md.CkuW5uER.lean.js +++ b/assets/garden_guide-to-incrementals_appeal-to-developers_index.md.DlM-Yrns.lean.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as i,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const m=e("h1",{class:"p-name"},"Guide to Incrementals/Appeal to Developers",-1),d=["innerHTML"],c=s("",14),b=JSON.parse('{"title":"Guide to Incrementals/Appeal to Developers","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/appeal-to-developers","title":"Guide to Incrementals/Appeal to Developers","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/appeal-to-developers/index.md","filePath":"garden/guide-to-incrementals/appeal-to-developers/index.md"}'),p={name:"garden/guide-to-incrementals/appeal-to-developers/index.md"},v=Object.assign(p,{setup(h){const t=o();return(u,g)=>(l(),i("div",null,[m,e("p",null,[r("636 words, ~3 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),c]))}});export{b as __pageData,v as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as i,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const m=e("h1",{class:"p-name"},"Guide to Incrementals/Appeal to Developers",-1),d=["innerHTML"],c=s("",14),b=JSON.parse('{"title":"Guide to Incrementals/Appeal to Developers","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/appeal-to-developers","title":"Guide to Incrementals/Appeal to Developers","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/appeal-to-developers/index.md","filePath":"garden/guide-to-incrementals/appeal-to-developers/index.md"}'),p={name:"garden/guide-to-incrementals/appeal-to-developers/index.md"},v=Object.assign(p,{setup(h){const t=o();return(u,g)=>(l(),i("div",null,[m,e("p",null,[r("636 words, ~3 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),c]))}});export{b as __pageData,v as default}; diff --git a/assets/garden_guide-to-incrementals_appeal-to-players_index.md.CA3L_dhG.js b/assets/garden_guide-to-incrementals_appeal-to-players_index.md.OPmcFpqr.js similarity index 99% rename from assets/garden_guide-to-incrementals_appeal-to-players_index.md.CA3L_dhG.js rename to assets/garden_guide-to-incrementals_appeal-to-players_index.md.OPmcFpqr.js index 9c50cbffb..c196e3e2b 100644 --- a/assets/garden_guide-to-incrementals_appeal-to-players_index.md.CA3L_dhG.js +++ b/assets/garden_guide-to-incrementals_appeal-to-players_index.md.OPmcFpqr.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as i,Q as e,K as s,u as a,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Guide to Incrementals/Appeal to Players",-1),m=["innerHTML"],g=r('
Referenced by:Incremental SocialKronos

This is something that has been discussed and analyzed by many people, and to some extent, I feel like everything that can be said on the topic already has. However, a lot of these analyses are from the perspective of those with not as much experience and involvement within the genre as I'd argue would be necessary for a fully contextualized answer. I'm interested in ludology and part of that includes interpreting games as art, and to that end what constitutes a game, let alone a "good game". Incremental games are oft criticized, unfairly in my biased opinion, of not even constituting games, such as was posited by this polygon article.

Numbers Going Up

This is a very common response to why people enjoy incremental games, although it's not one I find compels me personally, and I suspect it might be a stand-in for progression) or Guide to Incrementals/What is Content?. But reportedly, some people do just like seeing big numbers. I must reiterate I suspect the actual cause is seeing big numbers in context though - if you start at 1e1000 of a currency and get to 1e1001, that isn't going to feel as satisfying as going from 1e10 to 1e100, and in any case, I don't think a button that just adds a zero to your number will feel quite satisfying - I believe its the sense of having made progress, and comparing where you are to where you started and feeling like you've earned your way here that is enjoyable.

Progression

I think a strong sense of progression is seen as very enjoyable to many players of all sorts of genres - engine builder board games, RPGs, rogue_lites_, etc. Incremental games tend to have an extremely exaggerated sense of progression, which makes them very appealing.

Meta-progression is when games have some sort of progression that persists when other progress gets lost - for example, upgrades that persist between runs of a roguelite game. These are common mechanics in incremental games - in fact, its not uncommon to have multiple of these reset mechanics nested on top of each other, each with their own meta-progression. These are satisfying to players, although they can be a bit controversial. These mechanics can often be seen as an optional crutch, and in roguelite games, players often challenge themselves to win without any meta progression. Essentially these challenges argue that meta-progression de-emphasizes player skill by replacing it with time served. Incremental games, through their exaggerated progression, eschew that possibility though - they make it impossible to beat without the meta progression systems, as the meta-progression becomes an entire chapter of the gameplay. I'd argue this does not detract from the game, however, and is actually a part of what makes incremental games, and roguelikes, enjoyable to many players: meta-progression augments the increases in skill the player is naturally gaining as they play. In effect, it's not replacing the skill increase, but exaggerating it to make it feel more real to the player.

Effortlessness

Incremental games are so easy, a lot of them even have you progress while you're not playing! Part of the appeal is being able to feel like you're making progress while doing something actually productive - multitasking, in a way. In this sense, the game is more of a fidget toy - not something to think hard about and play actively, but something to click a few buttons every so often while you're paying attention to a lecture or studying or working. Of course, not all incremental games lend themselves to being played this way - it's specifically "idle" games that work like this. These are games that take an incredibly long amount of time to see all the content, stretching it as thin as possible, but they aren't expecting you to be sitting at your device playing it the entire time. They expect you to leave and come back later to make a bit of progress and repeat the cycle.

If you look at the higher-level play of most games, you'll see them perform difficult feats with ease and speed. They'll achieve a "flow state" that takes all their knowledge and experience of the game and uses it to play the game as instinctively as possible. It's incredible to watch things like Slay the Spire speed runs or competitive DDR-likes. I'd argue the goal of a lot of games with a competitive scene is to get so good that the game becomes effortless. In that sense, a game that allows you to reach that point earlier isn't any less legitimate, but rather lowers the barrier to entry by allowing more people to get "really good" at the game. And to be clear, (most) incremental games aren't trivially easy - they, and to an extent, every game will have some level of learning and improvement over time.

Addiction

A lot of these reasons for why incremental games appeal may have reminded you of why gambling appeals to people, particularly those prone to addiction. Indeed, incremental games are quite often criticized for their similarity to a skinner box. Some have gone as far as to say incremental games as a genre are commenting that all games are skinner boxes). The argument goes that some games are not fun, but rather condition players into continuing to play without actually getting anything from the experience. When tied to real-world money this is seen as predatory, and to a lesser extent, even free games may be feeding the addictive sides of people and making them more prone to seek out gambling or micro-transaction heavy games.

While incremental games can be fun and even healthy in certain contexts, they can exacerbate video game addiction more than other genres. If you feel like playing incremental games is taking priority over other things in your life, or manipulating your sleep schedule, it may be prudent to seek help. See r/StopGaming for resources.

Since incremental games are often built on extrinsic motivations in the form of progression systems, it's hard to argue whether players continue to play because they are enjoying the gameplay, or if they are just conditioned to keep doing it because the game keeps rewarding them. Unfortunately, it can often feel like it's the latter, as there isn't typically anything compelling about the "gameplay" of clicking a button and waiting. There may be a significant overlap between those who enjoy incremental games and those who are most prone to addiction, and there are often posts on r/incremental_games about someone either struggling with or overcoming video game addiction.

Strategy

Incremental games could be considered a subset of strategy games), and inherit the appeals of strategy games. This includes the appeal of feeling like you've found a good solution to a puzzle, or that you're learning more about the game and are improving at making decisions within it.

Note that strategy games are not all the same difficulty, as well. Cookie Clicker is probably easier than Starcraft 2 (although late game may beg to differ). Plenty of incremental games can be used as evidence that "easier" strategies may have their separate appeal to harder strategy games - players like to feel smart and that they figured the game out and have optimized or mastered it, and the game being easier doesn't detract from that sense of accomplishment as much as it allows more and more users to be able to reach the point where they gain that sense.

Avoiding Staleness

Incremental games tend to have "paradigm shifts", where the gameplay changes in a meaningful way at various times throughout the progression of the game. These upset and change the gameplay loop, which helps keep them from stagnating. This constant "freshness" to the gameplay can keep players engaged for longer, compared to a game with a repetitive and static gameplay loop.

Good Game Design

Incremental games tend to show their game design "plainly", so it's more readily apparent if a game has good game design while playing, even if you're not looking for it. While different players have different preferences and might enjoy different types of games more than others, there are underlying good and bad game design principles that players will notice the effects of. To be clear, this isn't talking about stuff like big numbers being enjoyable, where I can comfortably agree to disagree with other players. They don't intrinsically make my experience better, but I'm aware of those for whom it does and I won't argue against their feelings. However, the game designer in me does feel like there are some extremely clear-cut examples of good and bad game design philosophies.

Let's start by giving an example of a mechanic I think can be easily and strongly argued is good game design. There are of course many examples, but a personal favorite of mine is how DOOM encourages aggressive gameplay by linking health drops to melee attacks. It has an intended experience it's trying to give the player - immersing themselves as DOOM guy, who would not hide behind cover when low on health - and this mechanic does a great job at encouraging and effectively teaching players to behave properly. This is in sharp contrast to shooters like Call of Duty, which have you regen health passively, encouraging players to hide behind cover and wait after getting hit. Note that I'm not arguing CoD is poorly designed, as the games have different intended experiences. I'm specifically praising DOOM for having a mechanic that does a good job at ensuring the player has that intended experience.

To contrast with an example I think is bad game design, let's talk about shields in souls-likes. This is a bit of a famous example, and I highly recommend this video essay which spends quite a good bit of time on this topic. Essentially, the argument boils down to players of earlier games in the souls games using shields too much - playing slowly, conservatively, and ultimately having less fun. Players wanted to feel safe, so they ended up playing in a way that ruined the experience for them. The developers solved this by removing shields, apart from an intentionally bad one effectively mocking the playstyle, and it did its job at getting players to play more aggressively, and often have more fun.

To bring the conversation back to incrementals, I'm incredibly opinionated on what makes a good incremental game, which I'll discuss in the game design section. Suffice it to say, incremental games rely more on good game design than other genres, due to not having much to distract from bad game design. This helps (although imperfectly - gamers are a bit too tolerant of bad game design!) well-designed games rise to the top within the genre.

Artistic Merit

The discussion of whether video games are art has resulted in a pretty universal "yes, they are", but with some games the argument may still crop up. The reason why Incremental games are sometimes questioned is due to their perceived lack of complexity. However, even setting aside the fact that if players are having fun then it's not time wasted, I think games can have artistic merit that supersedes the necessity of having (any / engaging / "deep") gameplay. Incremental games are no less legitimate of a game or the "art" label because of any lack perceived lack of depth. For what it's worth, most art can be consumed with more ease than any video game - any painting, movie, sculpture, etc.

A lot of incrementals have a narrative context that can similarly qualify them as art. Cookie Clicker is, as has been pointed out numerous times before, commenting on excess and increasing production beyond any reasonable limits - devolving into increasing production for its own sake. Indeed, a lot of incremental games are written to comment upon various concepts like capitalism or tropes in games, as discussed when defining Incrementals). However, I'd like to argue most incremental games are still art, even without any narrative context. "Art" as a concept is pretty nebulous already, but I personally like those who define it as an act of expression more than any physical result. The creator and the context within which they created the art, and any meaning they put into it, are all relevant and a part of the art itself. Most incremental games have artistic merit from things like why the creator made it, why they chose to make it an incremental game, and why they made any particular design decision. Hell, even if you play through an entire incremental game without a single thought or feeling, that very fact it elicited nothing can itself be artistic merit!

I'm not an art major, and I may be taking a somewhat extreme take on what is art and what has artistic merit, but I'd argue the overall point stands that games, and incremental games specifically, can have artistic merit, which appeals to many gamers.

',29),b=JSON.parse('{"title":"Guide to Incrementals/Appeal to Players","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/appeal-to-players","title":"Guide to Incrementals/Appeal to Players","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/appeal-to-players/index.md","filePath":"garden/guide-to-incrementals/appeal-to-players/index.md"}'),c={name:"garden/guide-to-incrementals/appeal-to-players/index.md"},w=Object.assign(c,{setup(d){const t=o();return(p,u)=>(l(),i("div",null,[h,e("p",null,[s("2166 words, ~12 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),g]))}});export{b as __pageData,w as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as i,Q as e,K as s,u as a,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Guide to Incrementals/Appeal to Players",-1),m=["innerHTML"],g=r('
Referenced by:Incremental SocialKronos

This is something that has been discussed and analyzed by many people, and to some extent, I feel like everything that can be said on the topic already has. However, a lot of these analyses are from the perspective of those with not as much experience and involvement within the genre as I'd argue would be necessary for a fully contextualized answer. I'm interested in ludology and part of that includes interpreting games as art, and to that end what constitutes a game, let alone a "good game". Incremental games are oft criticized, unfairly in my biased opinion, of not even constituting games, such as was posited by this polygon article.

Numbers Going Up

This is a very common response to why people enjoy incremental games, although it's not one I find compels me personally, and I suspect it might be a stand-in for progression) or Guide to Incrementals/What is Content?. But reportedly, some people do just like seeing big numbers. I must reiterate I suspect the actual cause is seeing big numbers in context though - if you start at 1e1000 of a currency and get to 1e1001, that isn't going to feel as satisfying as going from 1e10 to 1e100, and in any case, I don't think a button that just adds a zero to your number will feel quite satisfying - I believe its the sense of having made progress, and comparing where you are to where you started and feeling like you've earned your way here that is enjoyable.

Progression

I think a strong sense of progression is seen as very enjoyable to many players of all sorts of genres - engine builder board games, RPGs, rogue_lites_, etc. Incremental games tend to have an extremely exaggerated sense of progression, which makes them very appealing.

Meta-progression is when games have some sort of progression that persists when other progress gets lost - for example, upgrades that persist between runs of a roguelite game. These are common mechanics in incremental games - in fact, its not uncommon to have multiple of these reset mechanics nested on top of each other, each with their own meta-progression. These are satisfying to players, although they can be a bit controversial. These mechanics can often be seen as an optional crutch, and in roguelite games, players often challenge themselves to win without any meta progression. Essentially these challenges argue that meta-progression de-emphasizes player skill by replacing it with time served. Incremental games, through their exaggerated progression, eschew that possibility though - they make it impossible to beat without the meta progression systems, as the meta-progression becomes an entire chapter of the gameplay. I'd argue this does not detract from the game, however, and is actually a part of what makes incremental games, and roguelikes, enjoyable to many players: meta-progression augments the increases in skill the player is naturally gaining as they play. In effect, it's not replacing the skill increase, but exaggerating it to make it feel more real to the player.

Effortlessness

Incremental games are so easy, a lot of them even have you progress while you're not playing! Part of the appeal is being able to feel like you're making progress while doing something actually productive - multitasking, in a way. In this sense, the game is more of a fidget toy - not something to think hard about and play actively, but something to click a few buttons every so often while you're paying attention to a lecture or studying or working. Of course, not all incremental games lend themselves to being played this way - it's specifically "idle" games that work like this. These are games that take an incredibly long amount of time to see all the content, stretching it as thin as possible, but they aren't expecting you to be sitting at your device playing it the entire time. They expect you to leave and come back later to make a bit of progress and repeat the cycle.

If you look at the higher-level play of most games, you'll see them perform difficult feats with ease and speed. They'll achieve a "flow state" that takes all their knowledge and experience of the game and uses it to play the game as instinctively as possible. It's incredible to watch things like Slay the Spire speed runs or competitive DDR-likes. I'd argue the goal of a lot of games with a competitive scene is to get so good that the game becomes effortless. In that sense, a game that allows you to reach that point earlier isn't any less legitimate, but rather lowers the barrier to entry by allowing more people to get "really good" at the game. And to be clear, (most) incremental games aren't trivially easy - they, and to an extent, every game will have some level of learning and improvement over time.

Addiction

A lot of these reasons for why incremental games appeal may have reminded you of why gambling appeals to people, particularly those prone to addiction. Indeed, incremental games are quite often criticized for their similarity to a skinner box. Some have gone as far as to say incremental games as a genre are commenting that all games are skinner boxes). The argument goes that some games are not fun, but rather condition players into continuing to play without actually getting anything from the experience. When tied to real-world money this is seen as predatory, and to a lesser extent, even free games may be feeding the addictive sides of people and making them more prone to seek out gambling or micro-transaction heavy games.

While incremental games can be fun and even healthy in certain contexts, they can exacerbate video game addiction more than other genres. If you feel like playing incremental games is taking priority over other things in your life, or manipulating your sleep schedule, it may be prudent to seek help. See r/StopGaming for resources.

Since incremental games are often built on extrinsic motivations in the form of progression systems, it's hard to argue whether players continue to play because they are enjoying the gameplay, or if they are just conditioned to keep doing it because the game keeps rewarding them. Unfortunately, it can often feel like it's the latter, as there isn't typically anything compelling about the "gameplay" of clicking a button and waiting. There may be a significant overlap between those who enjoy incremental games and those who are most prone to addiction, and there are often posts on r/incremental_games about someone either struggling with or overcoming video game addiction.

Strategy

Incremental games could be considered a subset of strategy games), and inherit the appeals of strategy games. This includes the appeal of feeling like you've found a good solution to a puzzle, or that you're learning more about the game and are improving at making decisions within it.

Note that strategy games are not all the same difficulty, as well. Cookie Clicker is probably easier than Starcraft 2 (although late game may beg to differ). Plenty of incremental games can be used as evidence that "easier" strategies may have their separate appeal to harder strategy games - players like to feel smart and that they figured the game out and have optimized or mastered it, and the game being easier doesn't detract from that sense of accomplishment as much as it allows more and more users to be able to reach the point where they gain that sense.

Avoiding Staleness

Incremental games tend to have "paradigm shifts", where the gameplay changes in a meaningful way at various times throughout the progression of the game. These upset and change the gameplay loop, which helps keep them from stagnating. This constant "freshness" to the gameplay can keep players engaged for longer, compared to a game with a repetitive and static gameplay loop.

Good Game Design

Incremental games tend to show their game design "plainly", so it's more readily apparent if a game has good game design while playing, even if you're not looking for it. While different players have different preferences and might enjoy different types of games more than others, there are underlying good and bad game design principles that players will notice the effects of. To be clear, this isn't talking about stuff like big numbers being enjoyable, where I can comfortably agree to disagree with other players. They don't intrinsically make my experience better, but I'm aware of those for whom it does and I won't argue against their feelings. However, the game designer in me does feel like there are some extremely clear-cut examples of good and bad game design philosophies.

Let's start by giving an example of a mechanic I think can be easily and strongly argued is good game design. There are of course many examples, but a personal favorite of mine is how DOOM encourages aggressive gameplay by linking health drops to melee attacks. It has an intended experience it's trying to give the player - immersing themselves as DOOM guy, who would not hide behind cover when low on health - and this mechanic does a great job at encouraging and effectively teaching players to behave properly. This is in sharp contrast to shooters like Call of Duty, which have you regen health passively, encouraging players to hide behind cover and wait after getting hit. Note that I'm not arguing CoD is poorly designed, as the games have different intended experiences. I'm specifically praising DOOM for having a mechanic that does a good job at ensuring the player has that intended experience.

To contrast with an example I think is bad game design, let's talk about shields in souls-likes. This is a bit of a famous example, and I highly recommend this video essay which spends quite a good bit of time on this topic. Essentially, the argument boils down to players of earlier games in the souls games using shields too much - playing slowly, conservatively, and ultimately having less fun. Players wanted to feel safe, so they ended up playing in a way that ruined the experience for them. The developers solved this by removing shields, apart from an intentionally bad one effectively mocking the playstyle, and it did its job at getting players to play more aggressively, and often have more fun.

To bring the conversation back to incrementals, I'm incredibly opinionated on what makes a good incremental game, which I'll discuss in the game design section. Suffice it to say, incremental games rely more on good game design than other genres, due to not having much to distract from bad game design. This helps (although imperfectly - gamers are a bit too tolerant of bad game design!) well-designed games rise to the top within the genre.

Artistic Merit

The discussion of whether video games are art has resulted in a pretty universal "yes, they are", but with some games the argument may still crop up. The reason why Incremental games are sometimes questioned is due to their perceived lack of complexity. However, even setting aside the fact that if players are having fun then it's not time wasted, I think games can have artistic merit that supersedes the necessity of having (any / engaging / "deep") gameplay. Incremental games are no less legitimate of a game or the "art" label because of any lack perceived lack of depth. For what it's worth, most art can be consumed with more ease than any video game - any painting, movie, sculpture, etc.

A lot of incrementals have a narrative context that can similarly qualify them as art. Cookie Clicker is, as has been pointed out numerous times before, commenting on excess and increasing production beyond any reasonable limits - devolving into increasing production for its own sake. Indeed, a lot of incremental games are written to comment upon various concepts like capitalism or tropes in games, as discussed when defining Incrementals). However, I'd like to argue most incremental games are still art, even without any narrative context. "Art" as a concept is pretty nebulous already, but I personally like those who define it as an act of expression more than any physical result. The creator and the context within which they created the art, and any meaning they put into it, are all relevant and a part of the art itself. Most incremental games have artistic merit from things like why the creator made it, why they chose to make it an incremental game, and why they made any particular design decision. Hell, even if you play through an entire incremental game without a single thought or feeling, that very fact it elicited nothing can itself be artistic merit!

I'm not an art major, and I may be taking a somewhat extreme take on what is art and what has artistic merit, but I'd argue the overall point stands that games, and incremental games specifically, can have artistic merit, which appeals to many gamers.

',29),b=JSON.parse('{"title":"Guide to Incrementals/Appeal to Players","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/appeal-to-players","title":"Guide to Incrementals/Appeal to Players","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/appeal-to-players/index.md","filePath":"garden/guide-to-incrementals/appeal-to-players/index.md"}'),c={name:"garden/guide-to-incrementals/appeal-to-players/index.md"},w=Object.assign(c,{setup(d){const t=o();return(p,u)=>(l(),i("div",null,[h,e("p",null,[s("2166 words, ~12 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),g]))}});export{b as __pageData,w as default}; diff --git a/assets/garden_guide-to-incrementals_appeal-to-players_index.md.CA3L_dhG.lean.js b/assets/garden_guide-to-incrementals_appeal-to-players_index.md.OPmcFpqr.lean.js similarity index 93% rename from assets/garden_guide-to-incrementals_appeal-to-players_index.md.CA3L_dhG.lean.js rename to assets/garden_guide-to-incrementals_appeal-to-players_index.md.OPmcFpqr.lean.js index 20eef21e0..d740d1ded 100644 --- a/assets/garden_guide-to-incrementals_appeal-to-players_index.md.CA3L_dhG.lean.js +++ b/assets/garden_guide-to-incrementals_appeal-to-players_index.md.OPmcFpqr.lean.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as i,Q as e,K as s,u as a,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Guide to Incrementals/Appeal to Players",-1),m=["innerHTML"],g=r("",29),b=JSON.parse('{"title":"Guide to Incrementals/Appeal to Players","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/appeal-to-players","title":"Guide to Incrementals/Appeal to Players","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/appeal-to-players/index.md","filePath":"garden/guide-to-incrementals/appeal-to-players/index.md"}'),c={name:"garden/guide-to-incrementals/appeal-to-players/index.md"},w=Object.assign(c,{setup(d){const t=o();return(p,u)=>(l(),i("div",null,[h,e("p",null,[s("2166 words, ~12 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),g]))}});export{b as __pageData,w as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as i,Q as e,K as s,u as a,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Guide to Incrementals/Appeal to Players",-1),m=["innerHTML"],g=r("",29),b=JSON.parse('{"title":"Guide to Incrementals/Appeal to Players","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/appeal-to-players","title":"Guide to Incrementals/Appeal to Players","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/appeal-to-players/index.md","filePath":"garden/guide-to-incrementals/appeal-to-players/index.md"}'),c={name:"garden/guide-to-incrementals/appeal-to-players/index.md"},w=Object.assign(c,{setup(d){const t=o();return(p,u)=>(l(),i("div",null,[h,e("p",null,[s("2166 words, ~12 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),g]))}});export{b as __pageData,w as default}; diff --git a/assets/garden_guide-to-incrementals_defining-the-genre_index.md.CbFSfPEj.js b/assets/garden_guide-to-incrementals_defining-the-genre_index.md.CRfSx2qs.js similarity index 99% rename from assets/garden_guide-to-incrementals_defining-the-genre_index.md.CbFSfPEj.js rename to assets/garden_guide-to-incrementals_defining-the-genre_index.md.CRfSx2qs.js index 2f75b7b7b..28cd8bdad 100644 --- a/assets/garden_guide-to-incrementals_defining-the-genre_index.md.CbFSfPEj.js +++ b/assets/garden_guide-to-incrementals_defining-the-genre_index.md.CRfSx2qs.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as o,Q as e,K as i,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Guide to Incrementals/Defining the Genre",-1),m=["innerHTML"],c=s('
Referenced by:Incremental SocialKronos

Video games are placed into genres for a variety of reasons. They can give a mental shorthand to set the player's expectations up, they can help a game market itself by its similarities to other, already popular games, and honestly, people just love categorization for its own sake. For this guide, it's important to define the genre so it is clear what games it's even talking about.

This poses a problem. Genres, being Social Constructs, suffer from the usual issues social constructs have of being vague and shifting over time. "Incremental", in particular, is a horribly vague way to define games. Most games have numbers going up in some form or another. We need a more specific definition - similar to how "strategy" can't just mean any game with any amount of strategy because that would be most games. What specifically differentiates incremental games from the rest?

"Incremental" implies it's a genre defined by a game mechanic, but all those game mechanics it could imply exist in many other games. Having a skill tree or upgrades doesn't make you incremental, and if a reset mechanic is all it takes then every roguelite would be an incremental as well. So clearly there's more to it than that - what makes an incremental an incremental?

I'd like to go over a couple of popular suggestions I've seen on defining the genre here. I have my personal preferences and will state them here, but I don't think there's a truly perfect answer.

BTW, if this article made you realize discourse around defining genres is actually a really interesting, even fascinating, topic, I recommend this video essay: Who Shot Guybrush Threepwood? | Genre and the Adventure Game.

Disclaimer: I mostly play incremental games on my computer, and my definitions will be heavily biased towards the games I'm familiar with.

Incrementals vs Idlers vs Clickers

Oftentimes people refer to this genre as idle games and/or clicker games. You'll even find a trend of oxymoronic game titles that contain both terms. "Incremental games" is the umbrella term both those terms fall under. However, I'd like to argue that not only is it better to just use the term "incremental games", but calling them "idle games" or "clicker games" is wrong. Almost universally, these terms are used interchangeably to refer to the same kind of game, where you start the game click spamming and eventually automate the process. Frankly, that kind of game deserves neither title, and the genre of incremental games has trended away from ever requiring click spamming, as it's a bad mechanic, anyways.

While these games do span a spectrum of how active it requires you to be, and sorting games by that metric can be useful for those looking for a particular experience, the borders of when an incremental game counts as an "idler" is too blurry for the term to be useful. "Incremental games" may not be a great descriptive term for the genre (hence this many thousands of words long page on defining what the genre even is), but it's strictly better than calling them "idler" or "clicker" games. This guide will always use the term "incremental games" unless quoting someone else, as it is the term you typically see on all modern games in the genre.

Incrementals as Parodies

Let's start with one of the most interesting definitions of incremental games. Incremental games appear to be distilled versions of games or genres, "revealing" the naked game design at the core of these games or genres not unlike how parodies comment upon their source material.

To understand what that means, think of how a casino uses skinner boxes to emotionally manipulate its customers to keep playing, but "dressing" up the skinner box with tons of stimuli to hide that ultimately the goal is to condition you into coming back compulsively. The idea that incremental games are parodies means taking the stance that at some level all games are similarly manipulating you, giving dopamine rewards in a way that manipulates you to keep playing while not necessarily giving you any value or fulfillment. Incremental games, then, are any games that plainly display the skinner box, and the manipulative core of the game, at the forefront of the experience.

While incremental games can be fun and even healthy in certain contexts, they can exacerbate video game addiction more than other genres. If you feel like playing incremental games is taking priority over other things in your life, or manipulating your sleep schedule, it may be prudent to seek help. See r/StopGaming for resources.

This "undressing" tends to go hand in hand with a reduced focus on aesthetics, often just printing the game state directly to the screen as text. This makes incremental games much easier to develop, particularly for those with programming skills but not art skills, but that's a tangent for why Incremental Games Guide to Incrementals/Appeal to Developers.

Before I continue, I'd like to make my stance clear that I love games and incremental games, and do not think they should be considered inherently bad or manipulative with the above logic. Skinner boxes are just a way of manipulating behavior via rewards. The games are still fun - that's the reward! I'd believe the real criticism here is that it is "empty fun", or "empty dopamine", that doesn't offer any additional value or sense of fulfillment. I don't think that's inherently bad in moderation, although it can become a problem if the game is manipulating you for profit-seeking, or if you play the game to the detriment of the other parts of your life.

Another interpretation of incremental games as parodies comes from several mainstream incremental games that are also parodies of capitalism, such as cookie clicker and adventure capitalist. It's a very common framework for incremental games to portray the ever-increasing numbers as an insatiable hunger for resources, like the ones observed within capitalism. Therefore, these games are used as evidence that the genre as a whole is about parody and commentary.

Popular videos on incremental games that portray the genre as parodies are Why Idle games make good satire, and how it was ruined. and Bad Game Design - Clicker Games. You may also be interested in this response to the latter video from a fan of incremental games: BadGood Game Design - Clicker Games.

I think that this definition ultimately ascribes a motive to the genre as a whole that only happens to apply to some of the more mainstream titles. There certainly are incremental games commenting on different things, including the genre itself as in the case of The Prestige Tree Classic, The Ascension Tree, or Omega Layers, but certainly not all. And of course, not all games that comment on something or parody something are incremental games! Additionally, a very large majority of incremental games are mobile games using these manipulative strategies to get players to spend as much money as possible - hell, Adventure Capitalist is ostensibly a critique on capitalism but features microtransactions and gameplay that manipulates you into buying them! These profit-seeking incremental games certainly belong within the genre but are hardly parodies when they too use manipulation to serve their interests. Also, from my own anecdotal experience, those who use this definition seem to do so from a fairly surface-level familiarity with the genre, and often in the context of criticizing the genre or the fans thereof.

Incrementals as NGU

Another broad definition often used is that incremental games are games where the focus of the game is "numbers going up". This definition proposes that other genres simply use increasing numbers as a means to an end, but incremental games uniquely only care about the numbers themselves going up. Put another way, it implies there should be no narrative justification for the numbers going up other than "why shouldn't they be going up?"

While this definition is common because it feels easy to understand, it is difficult to formally define. Often phrases are used to describe games using this framework, such as having an "exaggerated sense of progression" or "big" numbers. These terms are vague and don't demonstrate an actual threshold between non-incrementals and incrementals. Most games have a sense of progression, so when is it "exaggerated"? How big are "big" numbers? Most notably, RPGs that are typically not considered incrementals will often pass this definition.

Additionally, a lot of incrementals tend to have some theme guiding the gameplay, or at least the names of mechanics. This makes the line blurred between when numbers are going up for their own sake versus for a contextual reason. I believe this point is best illustrated that, while most RPGs are not considered incremental games, there is a sub-genre of "incremental RPGs" that typically relates to RPGs that perform combat automatically. This definition of incremental games does not support RPGs and "incremental RPGs" being on distinct sides of the line if the only difference between them is manual vs automatic combat.

Incrementals as Strategies

This is a rarer interpretation, but there are similarities between incremental games and strategy games, implying incrementals might just be a sub-genre of strategy games. By this approach, incremental games would be defined by their relation to strategy games, and how they involve player strategy. Incremental games are often large optimization problems - above all else, the actual gameplay the player is performing is deciding what to do next. The consequences of wrong decisions are typically more lenient in incremental games - such as just not making optimal progress - but they certainly get complex.

So if we accept the premise that incrementals could fall under strategy, we still need to define what makes a strategy game an incremental versus some other strategy sub-genre. This is a bit tricky due to one particular sub-genre of strategy games: Factory Builders.

Factory builders, such as Factorio or Satisfactory, are games about gaining ever increasing resources, optimizing production, and expanding more and more. That... sounds pretty similar, doesn't it? In fact, there's been some debate on whether factory builders would fall under the "incremental" umbrella. I think it's safe to say the two are certainly related, and probably have quite a bit of overlap in playerbase.

Roguelites as Incrementals?

Earlier on, I mentioned reset mechanics shouldn't be used in the definition because that could make all roguelites incrementals... But what if it does? A lot of incrementals can be described as games with a strong sense of progression, often with layers of meta-progression. Roguelites fit that bill to a T. What would make roguelites not incremental? I honestly don't think there's a good explanation here, but many fans of incremental games will state they do believe the two genres to be unrelated, even if there's a significant overlap between their player bases due to having similar appealing traits.

At this point, it'd be appropriate to consider what part of the definition of roguelites precludes them from also being incrementals, but that reveals a new problem: What are roguelites? They're usually defined as rogue_likes with meta-progression, but that just pushes the problem back a step: Incrementals aren't the only genre to have difficulties defining themselves, it seems! Roguelikes are another genre where the community argues over the formal definition of their genre, although that means we can borrow from their process of coming to a consensus, and maybe come across a viable definition for incremental games.

The Berlin Interpretation

By far the most popular way of defining roguelikes is the "Berlin Interpretation", which acknowledged the diversity of games within the genre and argued the definition should not be based on any ideals about what the genre ought to be, but rather defined by "its canon". They argued there are a handful of games that can be used to define the canon for roguelikes, and from those games, a list of factors can be derived to determine a game's "roguelikeness". The more factors a game has, the more of a roguelike it is. This strategy is very lenient, allowing a game to not present any specific factor so long as it shows enough, and accounts for the blurriness of any genre definition by not explicitly stating how many factors a game must have to qualify as a definite roguelike.

I believe this strategy for defining genres can be applied to other genres as well. A handful of games can be argued to be the incremental games canon, and a list of factors derived from them can be used to judge any game based on its "incrementalness". I'll propose such a canon and list of factors here, but by no means should it be considered the end-all-be-all.

Note: The "Temple of the roguelike", an authority within the genre, has since replaced the Berlin Interpretation with a new set of factors here: https://blog.roguetemple.com/what-is-a-traditional-roguelike/

A Modern Incremental Games Canon

Alright, time to get controversial. Up til now, I've been trying my best to stay objective and analytical, but now it's time to start making some opinionated decisions. I've created a list of games I think could be justified in making up a modern incremental games canon.

Before I mention the list, let's establish how I got to this list. First off, I'm really focusing on building a definition of the genre today, so I prefer modern games over traditional ones. A canon of culturally or historically significant titles to the genre would give a different list. Keep in mind the original Berlin interpretation (and the temple's update to it) were trying to define "traditional roguelikes", which is not my objective here. Building a canon that aims to trace the history of the genre is still valid and useful.

I'm also trying to ensure I pick a large breadth of incremental games, so I'm going to approach the list as a list of archetypes, with a single game to represent it but with other titles mentioned as other examples. This approach places each archetype as equally important, even if one only has a couple entries. Besides the impracticality of a canon that just includes every game, it'd be very biased towards games with large modding communities like Cookie Clicker or The Prestige Tree.

With all that behind us, here is a list of games I think could justifiably make up a Modern Incremental Games Canon:

  • Dodecadragons

    This game represents incremental games with many prestige layers that often have rapid resets and automate lower layers as more get unlocked. Other examples could also include The Prestige Tree, Really Grass Cutting Incremental Classic, Distance Incremental, or the massive modding community TPT has. A lot of the games I've personally worked on fall in this group, like Advent Incremental.

  • Evolve Idle

    This game represents incremental games with few prestige layers, very slow resets, and a focus on resource management. Typically involve some sort of worker allocation. Other examples would be Kitten's Game, Shark Game, or Magic Research.

  • (the) Gnorp Apologue

    This game represents incremental games with a central mechanic that gets added to by various other mechanics. All the mechanics remain relevant throughout the game, with different ones contributing most over time. Other examples include Nodebuster and To the Core. A lot of traditional games also fall in this archetype by having characters or buildings you level up, that each contribute additively to gaining the primary resources. These include Cookie Clicker, Clicker Heroes, and Realm Grinder. In a way, that makes the modern titles mentioned in this archetype the spiritual successors of those traditional games, and exemplifies how the genre has changed.

  • Idle Momentum

    This game represents incremental games that include polynomial growth as a central mechanic that is then built upon. Other examples include Antimatter Dimensions, Swarm Simulator, and Derivative Clicker.

  • Melvor Idle

    This game represents incremental games that are essentially a genre blend between incremental games and RPGs. Compared to other types of RPGs, these games have a focus on progressing while idle. Other examples would be IdleOn and a very large amount of mobile RPGs.

  • Stuck in Time

    This game represents incremental games that include a reset mechanic where there are pre-defined decisions being made during the course of the run. There's typically a concept of a playable character, whose actions are being "queued up" during a run, and these runs become longer or otherwise more productive as the game progresses. There are a lot of examples of this genre, including Cavernous II, Increlution, Progress Knight, Idle Loops, and Groundhog Life.

  • Universal Paperclips

    This game represents incremental games that involve several phases of completely distinct gameplay that fully replace the previous, called "paradigm shifts". Prestige layers are also often paradigm shifts, but this game represents paradigm shifts that are not reset mechanics but still transform the gameplay. Other examples would be Crank or A Dark Room. Spore would be an example that's not typically considered an incremental.

  • Unnamed Space Idle

    This game represents incremental games that focus on unlocking many different independent progression systems that boost each other, and all remain relevant throughout the course of the game. Other examples include NGU Idle, Anti-Idle, Idle Skilling, and Idle Wizard.

It may look like I've just shifted the problem down a level - rather than defining the genre, I'm now defining a bunch of sub-genres. However, the methods used here for defining the canon, and my attempt at ensuring a breadth of games by determining distinct archetypes, is just my approach. This list is additionally biased towards games I'm more familiar with, which will differ person to person. The only hard and fast rule is that every game on the list should be nearly universally accepted as an incremental game. So long as you do that, the factors should be relatively similar, although ofc individuals will still likely have small differences, as is the nature of socially constructed definitions.

Naturally this canon is a perpetual work-in-progress. I'm currently a bit uncertain about the distinctions between the evolve idle, melvor idle, and unnamed space idle archetypes. I could see those being rewritten as two or even a single archetype.

Unfolding

There are several related concepts mentioned in the canon - unfolding, prestige layers, and paradigm shifts. Unfolding is the umbrella term which includes the other two, and is clearly the highest possible value factor for an incremental. It's so common that for a while people referred to incrementals that exhibit this trait as "unfolding" games, to the point of trying to replace the term incremental due to their popularity.

There are many reasons for the appeal of unfolding mechanics. Oftentimes each mechanic builds on top of the existing mechanics, increasing the complexity of the game in steps so the player can follow along. In fact, sometimes the older mechanics will be entirely phased out (e.g. by automating them), so the complexity of the game remains roughly equal throughout the game. In any case, adding new mechanics regularly provides a sense of mystery, with the player anticipating what will happen next. They shake up the gameplay before it gets too stale - allowing the game to entertain for longer before the sense of Guide to Incrementals/What is Content? dissipates. Of the canon games selected above, I would argue every single one contains unfolding to some degree.

I should take a moment to say that while I'm hyping up this specific factor, we cannot just reduce the genre definition to "does it introduce new mechanics over time". Many games have paradigm shifts that are not incremental, so it's just an indicator of incrementalness. Every single canon game may show that it's common amongst incremental games, but could just as easily indicate that they're common in games in general.

High-Value Factors

I won't take as long to discuss the high and low-value factors, as you've already seen most of them brought up earlier on this page. As a reminder, a game does NOT need all of these to be an incremental game, but these are factors that each indicate a strong possibility the game is an incremental, so having several of these means they probably are. These factors apply to most of the canon incremental games.

"Pure UI" Display. Incrementals typically have a data-driven interface of the game state - there isn't a visual representation of the entities within the game. The interface resembles what might be a control panel in another genre, with a focus on numbers, buttons, and readouts rather than animated sprites or scenes. Even when there are visual elements, like item icons or simple enemy images, the player's main interaction is with non-diegetic, UI-focused components rather than immersive game visuals.

Reduced Consequences. Incrementals tend to have reduced repurcussions for misplaying. They very rarely have fail states, where often the largest consequence is simply not progressing - never losing progress.

Optimization Problems. The predominant gameplay of incrementals is typically solving optimization problems, from deciding which purchase to save up for to reasoning and deciding between different mutually exclusive options the game presents.

Resource Management. Incrementals tend to have a lot of resources within the game to keep track of.

Low-Value Factors

These are low-value factors, meaning they aren't as strongly correlated with incremental games. Incremental games may have none of these, and non-incrementals may have several of these - if a game only has low-value factors, they're probably not an incremental.

Fast Numeric Growth. Numbers in incremental games tend to grow faster than in other genres. There are more instances of superlinear growth. The larger the numbers get, the stronger of a signal this factor is.

Automation. As an incremental game progresses, the player often no longer has to deal with earlier mechanics, by having them either happen automatically or otherwise be replaced with an alternative that requires less player interaction.

Goal-Oriented. Incrementals are often heavily reliant on extrinsic motivation to guide the player. Typically this is through some sort of in-game goal to work towards, such as a certain amount of a resource being required to unlock or purchase something new.

Waiting is a Mechanic. In incremental games, the player may come across times where there is no action they can take, and the game will progress automatically instead. The player must wait for some amount of this automatic progress to occur before they can resume interaction with the game.

Are Roguelites Incrementals?

Having made our variation of the Berlin Interpretation for incremental games, we can compare it to the Berlin Interpretation to determine if there's enough overlap that any game that "passes" the Berlin Interpretation would also pass the incremental variant. That is to say, whether any roguelite would also be considered an incremental game.

The meta-progression of an incremental game could arguably be considered a paradigm shift, and certainly adds some resource management. Goal-oriented would probably also apply. I think anything other than those would be a stretch, and in my opinion that just isn't enough to qualify. To be totally honest, I was never expecting to conclude otherwise though 😉

Sub-Genres

There are some trends in incremental games that go beyond just being a commonly used mechanic, such that they deeply affect the rest of the game design. To a degree each of the games in the canon could arguably be part of distinct sub-genres, but I think these 4 deserve specific mentions:

Loops games are a sub-genre defined by having a core mechanic related to a loop, where the player is deciding the actions taken per loop. Notable examples include Idle Loops, Stuck in Time, Cavernous II, and Increlution. You may also argue Groundhog Life and Progress Knight fall into this sub-genre.

ITRTG-like games are a sub-genre defined by having a core mechanic based on clearing increasingly difficult battles and often tend to have a lot of different mechanics to become progressively stronger. Notable examples include Idling to Rule the Gods, NGU Idle, and Wizard and Minion Idle.

Polynomial Growth games are a sub-genre defined by having a core mechanic related to a higher degree polynomial. Notable examples include the base layer of Antimatter Dimensions and Swarm Simulator.

Upgrades Games is a category popular on flash games websites that featured games focused on buying upgrades that would allow you to attain more currency in some sort of minigame that would earn you more money to buy more upgrades, which I'd argue now belong under the fold of incremental games. Notable examples include the Learn to Fly series and Upgrade Complete.

Cultivation RPGs are a genre of games, books, and anime popular in China that center around being in a fantasy world with characters getting stronger over time. While few of them get translated into English, a fan of incremental games may find the available games interesting.

',70),y=JSON.parse('{"title":"Guide to Incrementals/Defining the Genre","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/defining-the-genre","title":"Guide to Incrementals/Defining the Genre","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/defining-the-genre/index.md","filePath":"garden/guide-to-incrementals/defining-the-genre/index.md"}'),g={name:"garden/guide-to-incrementals/defining-the-genre/index.md"},w=Object.assign(g,{setup(d){const a=n();return(u,p)=>(l(),o("div",null,[h,e("p",null,[i("4048 words, ~22 minute read. "),e("span",{innerHTML:t(r)[`site/${t(a).page.value.relativePath}`]},null,8,m)]),c]))}});export{y as __pageData,w as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as o,Q as e,K as i,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Guide to Incrementals/Defining the Genre",-1),m=["innerHTML"],c=s('
Referenced by:Incremental SocialKronos

Video games are placed into genres for a variety of reasons. They can give a mental shorthand to set the player's expectations up, they can help a game market itself by its similarities to other, already popular games, and honestly, people just love categorization for its own sake. For this guide, it's important to define the genre so it is clear what games it's even talking about.

This poses a problem. Genres, being Social Constructs, suffer from the usual issues social constructs have of being vague and shifting over time. "Incremental", in particular, is a horribly vague way to define games. Most games have numbers going up in some form or another. We need a more specific definition - similar to how "strategy" can't just mean any game with any amount of strategy because that would be most games. What specifically differentiates incremental games from the rest?

"Incremental" implies it's a genre defined by a game mechanic, but all those game mechanics it could imply exist in many other games. Having a skill tree or upgrades doesn't make you incremental, and if a reset mechanic is all it takes then every roguelite would be an incremental as well. So clearly there's more to it than that - what makes an incremental an incremental?

I'd like to go over a couple of popular suggestions I've seen on defining the genre here. I have my personal preferences and will state them here, but I don't think there's a truly perfect answer.

BTW, if this article made you realize discourse around defining genres is actually a really interesting, even fascinating, topic, I recommend this video essay: Who Shot Guybrush Threepwood? | Genre and the Adventure Game.

Disclaimer: I mostly play incremental games on my computer, and my definitions will be heavily biased towards the games I'm familiar with.

Incrementals vs Idlers vs Clickers

Oftentimes people refer to this genre as idle games and/or clicker games. You'll even find a trend of oxymoronic game titles that contain both terms. "Incremental games" is the umbrella term both those terms fall under. However, I'd like to argue that not only is it better to just use the term "incremental games", but calling them "idle games" or "clicker games" is wrong. Almost universally, these terms are used interchangeably to refer to the same kind of game, where you start the game click spamming and eventually automate the process. Frankly, that kind of game deserves neither title, and the genre of incremental games has trended away from ever requiring click spamming, as it's a bad mechanic, anyways.

While these games do span a spectrum of how active it requires you to be, and sorting games by that metric can be useful for those looking for a particular experience, the borders of when an incremental game counts as an "idler" is too blurry for the term to be useful. "Incremental games" may not be a great descriptive term for the genre (hence this many thousands of words long page on defining what the genre even is), but it's strictly better than calling them "idler" or "clicker" games. This guide will always use the term "incremental games" unless quoting someone else, as it is the term you typically see on all modern games in the genre.

Incrementals as Parodies

Let's start with one of the most interesting definitions of incremental games. Incremental games appear to be distilled versions of games or genres, "revealing" the naked game design at the core of these games or genres not unlike how parodies comment upon their source material.

To understand what that means, think of how a casino uses skinner boxes to emotionally manipulate its customers to keep playing, but "dressing" up the skinner box with tons of stimuli to hide that ultimately the goal is to condition you into coming back compulsively. The idea that incremental games are parodies means taking the stance that at some level all games are similarly manipulating you, giving dopamine rewards in a way that manipulates you to keep playing while not necessarily giving you any value or fulfillment. Incremental games, then, are any games that plainly display the skinner box, and the manipulative core of the game, at the forefront of the experience.

While incremental games can be fun and even healthy in certain contexts, they can exacerbate video game addiction more than other genres. If you feel like playing incremental games is taking priority over other things in your life, or manipulating your sleep schedule, it may be prudent to seek help. See r/StopGaming for resources.

This "undressing" tends to go hand in hand with a reduced focus on aesthetics, often just printing the game state directly to the screen as text. This makes incremental games much easier to develop, particularly for those with programming skills but not art skills, but that's a tangent for why Incremental Games Guide to Incrementals/Appeal to Developers.

Before I continue, I'd like to make my stance clear that I love games and incremental games, and do not think they should be considered inherently bad or manipulative with the above logic. Skinner boxes are just a way of manipulating behavior via rewards. The games are still fun - that's the reward! I'd believe the real criticism here is that it is "empty fun", or "empty dopamine", that doesn't offer any additional value or sense of fulfillment. I don't think that's inherently bad in moderation, although it can become a problem if the game is manipulating you for profit-seeking, or if you play the game to the detriment of the other parts of your life.

Another interpretation of incremental games as parodies comes from several mainstream incremental games that are also parodies of capitalism, such as cookie clicker and adventure capitalist. It's a very common framework for incremental games to portray the ever-increasing numbers as an insatiable hunger for resources, like the ones observed within capitalism. Therefore, these games are used as evidence that the genre as a whole is about parody and commentary.

Popular videos on incremental games that portray the genre as parodies are Why Idle games make good satire, and how it was ruined. and Bad Game Design - Clicker Games. You may also be interested in this response to the latter video from a fan of incremental games: BadGood Game Design - Clicker Games.

I think that this definition ultimately ascribes a motive to the genre as a whole that only happens to apply to some of the more mainstream titles. There certainly are incremental games commenting on different things, including the genre itself as in the case of The Prestige Tree Classic, The Ascension Tree, or Omega Layers, but certainly not all. And of course, not all games that comment on something or parody something are incremental games! Additionally, a very large majority of incremental games are mobile games using these manipulative strategies to get players to spend as much money as possible - hell, Adventure Capitalist is ostensibly a critique on capitalism but features microtransactions and gameplay that manipulates you into buying them! These profit-seeking incremental games certainly belong within the genre but are hardly parodies when they too use manipulation to serve their interests. Also, from my own anecdotal experience, those who use this definition seem to do so from a fairly surface-level familiarity with the genre, and often in the context of criticizing the genre or the fans thereof.

Incrementals as NGU

Another broad definition often used is that incremental games are games where the focus of the game is "numbers going up". This definition proposes that other genres simply use increasing numbers as a means to an end, but incremental games uniquely only care about the numbers themselves going up. Put another way, it implies there should be no narrative justification for the numbers going up other than "why shouldn't they be going up?"

While this definition is common because it feels easy to understand, it is difficult to formally define. Often phrases are used to describe games using this framework, such as having an "exaggerated sense of progression" or "big" numbers. These terms are vague and don't demonstrate an actual threshold between non-incrementals and incrementals. Most games have a sense of progression, so when is it "exaggerated"? How big are "big" numbers? Most notably, RPGs that are typically not considered incrementals will often pass this definition.

Additionally, a lot of incrementals tend to have some theme guiding the gameplay, or at least the names of mechanics. This makes the line blurred between when numbers are going up for their own sake versus for a contextual reason. I believe this point is best illustrated that, while most RPGs are not considered incremental games, there is a sub-genre of "incremental RPGs" that typically relates to RPGs that perform combat automatically. This definition of incremental games does not support RPGs and "incremental RPGs" being on distinct sides of the line if the only difference between them is manual vs automatic combat.

Incrementals as Strategies

This is a rarer interpretation, but there are similarities between incremental games and strategy games, implying incrementals might just be a sub-genre of strategy games. By this approach, incremental games would be defined by their relation to strategy games, and how they involve player strategy. Incremental games are often large optimization problems - above all else, the actual gameplay the player is performing is deciding what to do next. The consequences of wrong decisions are typically more lenient in incremental games - such as just not making optimal progress - but they certainly get complex.

So if we accept the premise that incrementals could fall under strategy, we still need to define what makes a strategy game an incremental versus some other strategy sub-genre. This is a bit tricky due to one particular sub-genre of strategy games: Factory Builders.

Factory builders, such as Factorio or Satisfactory, are games about gaining ever increasing resources, optimizing production, and expanding more and more. That... sounds pretty similar, doesn't it? In fact, there's been some debate on whether factory builders would fall under the "incremental" umbrella. I think it's safe to say the two are certainly related, and probably have quite a bit of overlap in playerbase.

Roguelites as Incrementals?

Earlier on, I mentioned reset mechanics shouldn't be used in the definition because that could make all roguelites incrementals... But what if it does? A lot of incrementals can be described as games with a strong sense of progression, often with layers of meta-progression. Roguelites fit that bill to a T. What would make roguelites not incremental? I honestly don't think there's a good explanation here, but many fans of incremental games will state they do believe the two genres to be unrelated, even if there's a significant overlap between their player bases due to having similar appealing traits.

At this point, it'd be appropriate to consider what part of the definition of roguelites precludes them from also being incrementals, but that reveals a new problem: What are roguelites? They're usually defined as rogue_likes with meta-progression, but that just pushes the problem back a step: Incrementals aren't the only genre to have difficulties defining themselves, it seems! Roguelikes are another genre where the community argues over the formal definition of their genre, although that means we can borrow from their process of coming to a consensus, and maybe come across a viable definition for incremental games.

The Berlin Interpretation

By far the most popular way of defining roguelikes is the "Berlin Interpretation", which acknowledged the diversity of games within the genre and argued the definition should not be based on any ideals about what the genre ought to be, but rather defined by "its canon". They argued there are a handful of games that can be used to define the canon for roguelikes, and from those games, a list of factors can be derived to determine a game's "roguelikeness". The more factors a game has, the more of a roguelike it is. This strategy is very lenient, allowing a game to not present any specific factor so long as it shows enough, and accounts for the blurriness of any genre definition by not explicitly stating how many factors a game must have to qualify as a definite roguelike.

I believe this strategy for defining genres can be applied to other genres as well. A handful of games can be argued to be the incremental games canon, and a list of factors derived from them can be used to judge any game based on its "incrementalness". I'll propose such a canon and list of factors here, but by no means should it be considered the end-all-be-all.

Note: The "Temple of the roguelike", an authority within the genre, has since replaced the Berlin Interpretation with a new set of factors here: https://blog.roguetemple.com/what-is-a-traditional-roguelike/

A Modern Incremental Games Canon

Alright, time to get controversial. Up til now, I've been trying my best to stay objective and analytical, but now it's time to start making some opinionated decisions. I've created a list of games I think could be justified in making up a modern incremental games canon.

Before I mention the list, let's establish how I got to this list. First off, I'm really focusing on building a definition of the genre today, so I prefer modern games over traditional ones. A canon of culturally or historically significant titles to the genre would give a different list. Keep in mind the original Berlin interpretation (and the temple's update to it) were trying to define "traditional roguelikes", which is not my objective here. Building a canon that aims to trace the history of the genre is still valid and useful.

I'm also trying to ensure I pick a large breadth of incremental games, so I'm going to approach the list as a list of archetypes, with a single game to represent it but with other titles mentioned as other examples. This approach places each archetype as equally important, even if one only has a couple entries. Besides the impracticality of a canon that just includes every game, it'd be very biased towards games with large modding communities like Cookie Clicker or The Prestige Tree.

With all that behind us, here is a list of games I think could justifiably make up a Modern Incremental Games Canon:

  • Dodecadragons

    This game represents incremental games with many prestige layers that often have rapid resets and automate lower layers as more get unlocked. Other examples could also include The Prestige Tree, Really Grass Cutting Incremental Classic, Distance Incremental, or the massive modding community TPT has. A lot of the games I've personally worked on fall in this group, like Advent Incremental.

  • Evolve Idle

    This game represents incremental games with few prestige layers, very slow resets, and a focus on resource management. Typically involve some sort of worker allocation. Other examples would be Kitten's Game, Shark Game, or Magic Research.

  • (the) Gnorp Apologue

    This game represents incremental games with a central mechanic that gets added to by various other mechanics. All the mechanics remain relevant throughout the game, with different ones contributing most over time. Other examples include Nodebuster and To the Core. A lot of traditional games also fall in this archetype by having characters or buildings you level up, that each contribute additively to gaining the primary resources. These include Cookie Clicker, Clicker Heroes, and Realm Grinder. In a way, that makes the modern titles mentioned in this archetype the spiritual successors of those traditional games, and exemplifies how the genre has changed.

  • Idle Momentum

    This game represents incremental games that include polynomial growth as a central mechanic that is then built upon. Other examples include Antimatter Dimensions, Swarm Simulator, and Derivative Clicker.

  • Melvor Idle

    This game represents incremental games that are essentially a genre blend between incremental games and RPGs. Compared to other types of RPGs, these games have a focus on progressing while idle. Other examples would be IdleOn and a very large amount of mobile RPGs.

  • Stuck in Time

    This game represents incremental games that include a reset mechanic where there are pre-defined decisions being made during the course of the run. There's typically a concept of a playable character, whose actions are being "queued up" during a run, and these runs become longer or otherwise more productive as the game progresses. There are a lot of examples of this genre, including Cavernous II, Increlution, Progress Knight, Idle Loops, and Groundhog Life.

  • Universal Paperclips

    This game represents incremental games that involve several phases of completely distinct gameplay that fully replace the previous, called "paradigm shifts". Prestige layers are also often paradigm shifts, but this game represents paradigm shifts that are not reset mechanics but still transform the gameplay. Other examples would be Crank or A Dark Room. Spore would be an example that's not typically considered an incremental.

  • Unnamed Space Idle

    This game represents incremental games that focus on unlocking many different independent progression systems that boost each other, and all remain relevant throughout the course of the game. Other examples include NGU Idle, Anti-Idle, Idle Skilling, and Idle Wizard.

It may look like I've just shifted the problem down a level - rather than defining the genre, I'm now defining a bunch of sub-genres. However, the methods used here for defining the canon, and my attempt at ensuring a breadth of games by determining distinct archetypes, is just my approach. This list is additionally biased towards games I'm more familiar with, which will differ person to person. The only hard and fast rule is that every game on the list should be nearly universally accepted as an incremental game. So long as you do that, the factors should be relatively similar, although ofc individuals will still likely have small differences, as is the nature of socially constructed definitions.

Naturally this canon is a perpetual work-in-progress. I'm currently a bit uncertain about the distinctions between the evolve idle, melvor idle, and unnamed space idle archetypes. I could see those being rewritten as two or even a single archetype.

Unfolding

There are several related concepts mentioned in the canon - unfolding, prestige layers, and paradigm shifts. Unfolding is the umbrella term which includes the other two, and is clearly the highest possible value factor for an incremental. It's so common that for a while people referred to incrementals that exhibit this trait as "unfolding" games, to the point of trying to replace the term incremental due to their popularity.

There are many reasons for the appeal of unfolding mechanics. Oftentimes each mechanic builds on top of the existing mechanics, increasing the complexity of the game in steps so the player can follow along. In fact, sometimes the older mechanics will be entirely phased out (e.g. by automating them), so the complexity of the game remains roughly equal throughout the game. In any case, adding new mechanics regularly provides a sense of mystery, with the player anticipating what will happen next. They shake up the gameplay before it gets too stale - allowing the game to entertain for longer before the sense of Guide to Incrementals/What is Content? dissipates. Of the canon games selected above, I would argue every single one contains unfolding to some degree.

I should take a moment to say that while I'm hyping up this specific factor, we cannot just reduce the genre definition to "does it introduce new mechanics over time". Many games have paradigm shifts that are not incremental, so it's just an indicator of incrementalness. Every single canon game may show that it's common amongst incremental games, but could just as easily indicate that they're common in games in general.

High-Value Factors

I won't take as long to discuss the high and low-value factors, as you've already seen most of them brought up earlier on this page. As a reminder, a game does NOT need all of these to be an incremental game, but these are factors that each indicate a strong possibility the game is an incremental, so having several of these means they probably are. These factors apply to most of the canon incremental games.

"Pure UI" Display. Incrementals typically have a data-driven interface of the game state - there isn't a visual representation of the entities within the game. The interface resembles what might be a control panel in another genre, with a focus on numbers, buttons, and readouts rather than animated sprites or scenes. Even when there are visual elements, like item icons or simple enemy images, the player's main interaction is with non-diegetic, UI-focused components rather than immersive game visuals.

Reduced Consequences. Incrementals tend to have reduced repurcussions for misplaying. They very rarely have fail states, where often the largest consequence is simply not progressing - never losing progress.

Optimization Problems. The predominant gameplay of incrementals is typically solving optimization problems, from deciding which purchase to save up for to reasoning and deciding between different mutually exclusive options the game presents.

Resource Management. Incrementals tend to have a lot of resources within the game to keep track of.

Low-Value Factors

These are low-value factors, meaning they aren't as strongly correlated with incremental games. Incremental games may have none of these, and non-incrementals may have several of these - if a game only has low-value factors, they're probably not an incremental.

Fast Numeric Growth. Numbers in incremental games tend to grow faster than in other genres. There are more instances of superlinear growth. The larger the numbers get, the stronger of a signal this factor is.

Automation. As an incremental game progresses, the player often no longer has to deal with earlier mechanics, by having them either happen automatically or otherwise be replaced with an alternative that requires less player interaction.

Goal-Oriented. Incrementals are often heavily reliant on extrinsic motivation to guide the player. Typically this is through some sort of in-game goal to work towards, such as a certain amount of a resource being required to unlock or purchase something new.

Waiting is a Mechanic. In incremental games, the player may come across times where there is no action they can take, and the game will progress automatically instead. The player must wait for some amount of this automatic progress to occur before they can resume interaction with the game.

Are Roguelites Incrementals?

Having made our variation of the Berlin Interpretation for incremental games, we can compare it to the Berlin Interpretation to determine if there's enough overlap that any game that "passes" the Berlin Interpretation would also pass the incremental variant. That is to say, whether any roguelite would also be considered an incremental game.

The meta-progression of an incremental game could arguably be considered a paradigm shift, and certainly adds some resource management. Goal-oriented would probably also apply. I think anything other than those would be a stretch, and in my opinion that just isn't enough to qualify. To be totally honest, I was never expecting to conclude otherwise though 😉

Sub-Genres

There are some trends in incremental games that go beyond just being a commonly used mechanic, such that they deeply affect the rest of the game design. To a degree each of the games in the canon could arguably be part of distinct sub-genres, but I think these 4 deserve specific mentions:

Loops games are a sub-genre defined by having a core mechanic related to a loop, where the player is deciding the actions taken per loop. Notable examples include Idle Loops, Stuck in Time, Cavernous II, and Increlution. You may also argue Groundhog Life and Progress Knight fall into this sub-genre.

ITRTG-like games are a sub-genre defined by having a core mechanic based on clearing increasingly difficult battles and often tend to have a lot of different mechanics to become progressively stronger. Notable examples include Idling to Rule the Gods, NGU Idle, and Wizard and Minion Idle.

Polynomial Growth games are a sub-genre defined by having a core mechanic related to a higher degree polynomial. Notable examples include the base layer of Antimatter Dimensions and Swarm Simulator.

Upgrades Games is a category popular on flash games websites that featured games focused on buying upgrades that would allow you to attain more currency in some sort of minigame that would earn you more money to buy more upgrades, which I'd argue now belong under the fold of incremental games. Notable examples include the Learn to Fly series and Upgrade Complete.

Cultivation RPGs are a genre of games, books, and anime popular in China that center around being in a fantasy world with characters getting stronger over time. While few of them get translated into English, a fan of incremental games may find the available games interesting.

',70),y=JSON.parse('{"title":"Guide to Incrementals/Defining the Genre","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/defining-the-genre","title":"Guide to Incrementals/Defining the Genre","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/defining-the-genre/index.md","filePath":"garden/guide-to-incrementals/defining-the-genre/index.md"}'),g={name:"garden/guide-to-incrementals/defining-the-genre/index.md"},w=Object.assign(g,{setup(d){const a=n();return(u,p)=>(l(),o("div",null,[h,e("p",null,[i("4048 words, ~22 minute read. "),e("span",{innerHTML:t(r)[`site/${t(a).page.value.relativePath}`]},null,8,m)]),c]))}});export{y as __pageData,w as default}; diff --git a/assets/garden_guide-to-incrementals_defining-the-genre_index.md.CbFSfPEj.lean.js b/assets/garden_guide-to-incrementals_defining-the-genre_index.md.CRfSx2qs.lean.js similarity index 93% rename from assets/garden_guide-to-incrementals_defining-the-genre_index.md.CbFSfPEj.lean.js rename to assets/garden_guide-to-incrementals_defining-the-genre_index.md.CRfSx2qs.lean.js index 59bd02d9e..ab0daf65f 100644 --- a/assets/garden_guide-to-incrementals_defining-the-genre_index.md.CbFSfPEj.lean.js +++ b/assets/garden_guide-to-incrementals_defining-the-genre_index.md.CRfSx2qs.lean.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as o,Q as e,K as i,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Guide to Incrementals/Defining the Genre",-1),m=["innerHTML"],c=s("",70),y=JSON.parse('{"title":"Guide to Incrementals/Defining the Genre","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/defining-the-genre","title":"Guide to Incrementals/Defining the Genre","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/defining-the-genre/index.md","filePath":"garden/guide-to-incrementals/defining-the-genre/index.md"}'),g={name:"garden/guide-to-incrementals/defining-the-genre/index.md"},w=Object.assign(g,{setup(d){const a=n();return(u,p)=>(l(),o("div",null,[h,e("p",null,[i("4048 words, ~22 minute read. "),e("span",{innerHTML:t(r)[`site/${t(a).page.value.relativePath}`]},null,8,m)]),c]))}});export{y as __pageData,w as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as o,Q as e,K as i,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Guide to Incrementals/Defining the Genre",-1),m=["innerHTML"],c=s("",70),y=JSON.parse('{"title":"Guide to Incrementals/Defining the Genre","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/defining-the-genre","title":"Guide to Incrementals/Defining the Genre","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/defining-the-genre/index.md","filePath":"garden/guide-to-incrementals/defining-the-genre/index.md"}'),g={name:"garden/guide-to-incrementals/defining-the-genre/index.md"},w=Object.assign(g,{setup(d){const a=n();return(u,p)=>(l(),o("div",null,[h,e("p",null,[i("4048 words, ~22 minute read. "),e("span",{innerHTML:t(r)[`site/${t(a).page.value.relativePath}`]},null,8,m)]),c]))}});export{y as __pageData,w as default}; diff --git a/assets/garden_guide-to-incrementals_index.md.5BLfRn5b.js b/assets/garden_guide-to-incrementals_index.md.CaQpBwBw.js similarity index 98% rename from assets/garden_guide-to-incrementals_index.md.5BLfRn5b.js rename to assets/garden_guide-to-incrementals_index.md.CaQpBwBw.js index 736cce395..24595cf77 100644 --- a/assets/garden_guide-to-incrementals_index.md.5BLfRn5b.js +++ b/assets/garden_guide-to-incrementals_index.md.CaQpBwBw.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as o,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Guide to Incrementals",-1),m=["innerHTML"],c=s('
Referenced by:My Personal Website

This is a comprehensive guide to Incremental Games, a genre of video games. It will explore defining the genre, why it's appealing, and how to design and build your own incremental game. Along the way will be interactive examples, snippets from other creators, and relevant material to contextualize everything.

Note: This is an incomplete document. I want to keep adding opinions and opposing views from other incremental games developers, and add interactive examples to illustrate various points regarding game design and balancing. Consider this a living document - and see the changelog at the end.

Why am I making this?

That's a good question! What authority do I have to be making this guide? I haven't made the best incremental games, nor the most incremental games, certainly not the most popular ones either. But I do have some formal education in game development, know a lot of incremental game devs (as well as other game devs), and have a passionate interest in ludology, classifying genres, etc. I've also made a couple of incremental games) myself.

If you have any additional questions about my credentials or anything on this site, feel free to reach out!

Ludology

Making an Incremental

',11),y=JSON.parse('{"title":"Guide to Incrementals","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals","title":"Guide to Incrementals","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/index.md","filePath":"garden/guide-to-incrementals/index.md"}'),g={name:"garden/guide-to-incrementals/index.md"},v=Object.assign(g,{setup(h){const t=i();return(u,p)=>(l(),o("div",null,[d,e("p",null,[r("230 words, ~1 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),c]))}});export{y as __pageData,v as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as o,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Guide to Incrementals",-1),m=["innerHTML"],c=s('
Referenced by:My Personal Website

This is a comprehensive guide to Incremental Games, a genre of video games. It will explore defining the genre, why it's appealing, and how to design and build your own incremental game. Along the way will be interactive examples, snippets from other creators, and relevant material to contextualize everything.

Note: This is an incomplete document. I want to keep adding opinions and opposing views from other incremental games developers, and add interactive examples to illustrate various points regarding game design and balancing. Consider this a living document - and see the changelog at the end.

Why am I making this?

That's a good question! What authority do I have to be making this guide? I haven't made the best incremental games, nor the most incremental games, certainly not the most popular ones either. But I do have some formal education in game development, know a lot of incremental game devs (as well as other game devs), and have a passionate interest in ludology, classifying genres, etc. I've also made a couple of incremental games) myself.

If you have any additional questions about my credentials or anything on this site, feel free to reach out!

Ludology

Making an Incremental

',11),y=JSON.parse('{"title":"Guide to Incrementals","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals","title":"Guide to Incrementals","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/index.md","filePath":"garden/guide-to-incrementals/index.md"}'),g={name:"garden/guide-to-incrementals/index.md"},v=Object.assign(g,{setup(h){const t=i();return(u,p)=>(l(),o("div",null,[d,e("p",null,[r("230 words, ~1 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),c]))}});export{y as __pageData,v as default}; diff --git a/assets/garden_guide-to-incrementals_index.md.5BLfRn5b.lean.js b/assets/garden_guide-to-incrementals_index.md.CaQpBwBw.lean.js similarity index 92% rename from assets/garden_guide-to-incrementals_index.md.5BLfRn5b.lean.js rename to assets/garden_guide-to-incrementals_index.md.CaQpBwBw.lean.js index e1918b492..d73a35175 100644 --- a/assets/garden_guide-to-incrementals_index.md.5BLfRn5b.lean.js +++ b/assets/garden_guide-to-incrementals_index.md.CaQpBwBw.lean.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as o,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Guide to Incrementals",-1),m=["innerHTML"],c=s("",11),y=JSON.parse('{"title":"Guide to Incrementals","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals","title":"Guide to Incrementals","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/index.md","filePath":"garden/guide-to-incrementals/index.md"}'),g={name:"garden/guide-to-incrementals/index.md"},v=Object.assign(g,{setup(h){const t=i();return(u,p)=>(l(),o("div",null,[d,e("p",null,[r("230 words, ~1 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),c]))}});export{y as __pageData,v as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as o,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Guide to Incrementals",-1),m=["innerHTML"],c=s("",11),y=JSON.parse('{"title":"Guide to Incrementals","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals","title":"Guide to Incrementals","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/index.md","filePath":"garden/guide-to-incrementals/index.md"}'),g={name:"garden/guide-to-incrementals/index.md"},v=Object.assign(g,{setup(h){const t=i();return(u,p)=>(l(),o("div",null,[d,e("p",null,[r("230 words, ~1 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),c]))}});export{y as __pageData,v as default}; diff --git a/assets/garden_guide-to-incrementals_navigating-criticism_index.md.uvCjn02L.js b/assets/garden_guide-to-incrementals_navigating-criticism_index.md.DivZ76BD.js similarity index 98% rename from assets/garden_guide-to-incrementals_navigating-criticism_index.md.uvCjn02L.js rename to assets/garden_guide-to-incrementals_navigating-criticism_index.md.DivZ76BD.js index cdce26abc..7f3c93818 100644 --- a/assets/garden_guide-to-incrementals_navigating-criticism_index.md.uvCjn02L.js +++ b/assets/garden_guide-to-incrementals_navigating-criticism_index.md.DivZ76BD.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as o,Q as e,K as r,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Guide to Incrementals/Navigating Criticism",-1),d=["innerHTML"],u=s('
Referenced by:Incremental SocialKronos

Developing games is fun and exciting and teaches a lot of wonderful skills - I enthusiastically encourage anyone with an interest in game development to try it out - and incremental games are a wonderful way to get started. However, there are many challenges young and inexperienced developers have to face, and I think the hardest one - harder than coding, debugging, balancing, etc. - is handling criticism. When you put your heart and soul into a game it is natural to feel very vulnerable. While I think there's a lot communities can do to ensure they're welcoming, positive and constructive with their criticisms, inevitably you will eventually read some, and potentially a lot, of comments that can deeply affect you. No one is immune to this, from young incremental game developers to the largest content creators you can think of. That's why it's important to be able to process and navigate criticism, because ultimately collecting feedback is essential to the journey to becoming a better developer. On this page, we'll explore how to embrace criticism, grow from it, and continue to post your games publicly with confidence.

Reading Feedback

Game development is a skill that takes time and practice to get truly great at. Criticism and other constructive feedback are vital to continually improving. It's useful to look at the criticism as solely a tool for improving this game and future games - that is to say, it should never be used against you as a person. Insults towards the developer(s) themselves are never okay and should not be allowed within whatever community you're sharing your works in. If you do come across a comment you interpret as an attack upon your person, you should report it. For other negative comments, try not to internalize them; instead, focus on improving the game. By distancing your own identity from your work emotionally, you can better analyze the game and use the feedback to your advantage.

Not all feedback is made equal, and you don't need to feel compelled to read and obey every piece of feedback you receive. Learn to distinguish between constructive feedback and unhelpful comments. Constructive feedback typically offers specific suggestions for improvement, while unhelpful comments are often vague or hurtful. Prioritize the former and disregard the latter. That said, most feedback you get will not be from game developers, so take specific suggestions with a grain of salt. Determine the actual problem they're experiencing, and design what you believe the best solution to that problem would be, regardless if that's the specific solution the player asked for. And keep in mind, due to different player preferences you'll never satisfy everyone, and you don't need to. Ultimately if even just you find the game fun, then that's a success.

Seeking Feedback

When deciding where to share your game, consider the type of players you anticipate getting, and the kind of feedback you can anticipate receiving. Different communities will have different levels of support for learning developers, and certain communities may prefer certain types of games or mechanics. It's important to get a diverse set of feedback focused on players you think will enjoy the specific game you're making.

Collecting feedback from other game developers is incredibly helpful. They've trained themselves to recognize good and bad game design and how to articulate the differences, and from my experience are much more likely to leave positive and constructive comments since they've been in your shoes before! They understand the struggles and can offer guidance and emotional support.

Responding to Feedback

Negative feedback can naturally feel like an attack, and it's okay to get angry. However, lashing back is never the appropriate response. It's best to cool off IRL, and keep in mind all the positive comments you've received. There's a concept in Psychology called negative bias that explains how negative feedback tends to stick with us much more prominently than positive feedback, so it's useful to regularly remind yourself of all the positive feedback you've received. Celebrate your successes, no matter how small they may seem - getting a game to a state you can publicly share it with people is an accomplishment in and of itself!

Remember your passion and your initial reasons for getting into game development. The journey will have its ups and downs, but staying true to your vision and passion will keep you motivated.

',12),v=JSON.parse('{"title":"Guide to Incrementals/Navigating Criticism","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/navigating-criticism","title":"Guide to Incrementals/Navigating Criticism","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/navigating-criticism/index.md","filePath":"garden/guide-to-incrementals/navigating-criticism/index.md"}'),m={name:"garden/guide-to-incrementals/navigating-criticism/index.md"},b=Object.assign(m,{setup(h){const a=n();return(g,p)=>(l(),o("div",null,[c,e("p",null,[r("747 words, ~4 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),u]))}});export{v as __pageData,b as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as o,Q as e,K as r,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Guide to Incrementals/Navigating Criticism",-1),d=["innerHTML"],u=s('
Referenced by:Incremental SocialKronos

Developing games is fun and exciting and teaches a lot of wonderful skills - I enthusiastically encourage anyone with an interest in game development to try it out - and incremental games are a wonderful way to get started. However, there are many challenges young and inexperienced developers have to face, and I think the hardest one - harder than coding, debugging, balancing, etc. - is handling criticism. When you put your heart and soul into a game it is natural to feel very vulnerable. While I think there's a lot communities can do to ensure they're welcoming, positive and constructive with their criticisms, inevitably you will eventually read some, and potentially a lot, of comments that can deeply affect you. No one is immune to this, from young incremental game developers to the largest content creators you can think of. That's why it's important to be able to process and navigate criticism, because ultimately collecting feedback is essential to the journey to becoming a better developer. On this page, we'll explore how to embrace criticism, grow from it, and continue to post your games publicly with confidence.

Reading Feedback

Game development is a skill that takes time and practice to get truly great at. Criticism and other constructive feedback are vital to continually improving. It's useful to look at the criticism as solely a tool for improving this game and future games - that is to say, it should never be used against you as a person. Insults towards the developer(s) themselves are never okay and should not be allowed within whatever community you're sharing your works in. If you do come across a comment you interpret as an attack upon your person, you should report it. For other negative comments, try not to internalize them; instead, focus on improving the game. By distancing your own identity from your work emotionally, you can better analyze the game and use the feedback to your advantage.

Not all feedback is made equal, and you don't need to feel compelled to read and obey every piece of feedback you receive. Learn to distinguish between constructive feedback and unhelpful comments. Constructive feedback typically offers specific suggestions for improvement, while unhelpful comments are often vague or hurtful. Prioritize the former and disregard the latter. That said, most feedback you get will not be from game developers, so take specific suggestions with a grain of salt. Determine the actual problem they're experiencing, and design what you believe the best solution to that problem would be, regardless if that's the specific solution the player asked for. And keep in mind, due to different player preferences you'll never satisfy everyone, and you don't need to. Ultimately if even just you find the game fun, then that's a success.

Seeking Feedback

When deciding where to share your game, consider the type of players you anticipate getting, and the kind of feedback you can anticipate receiving. Different communities will have different levels of support for learning developers, and certain communities may prefer certain types of games or mechanics. It's important to get a diverse set of feedback focused on players you think will enjoy the specific game you're making.

Collecting feedback from other game developers is incredibly helpful. They've trained themselves to recognize good and bad game design and how to articulate the differences, and from my experience are much more likely to leave positive and constructive comments since they've been in your shoes before! They understand the struggles and can offer guidance and emotional support.

Responding to Feedback

Negative feedback can naturally feel like an attack, and it's okay to get angry. However, lashing back is never the appropriate response. It's best to cool off IRL, and keep in mind all the positive comments you've received. There's a concept in Psychology called negative bias that explains how negative feedback tends to stick with us much more prominently than positive feedback, so it's useful to regularly remind yourself of all the positive feedback you've received. Celebrate your successes, no matter how small they may seem - getting a game to a state you can publicly share it with people is an accomplishment in and of itself!

Remember your passion and your initial reasons for getting into game development. The journey will have its ups and downs, but staying true to your vision and passion will keep you motivated.

',12),v=JSON.parse('{"title":"Guide to Incrementals/Navigating Criticism","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/navigating-criticism","title":"Guide to Incrementals/Navigating Criticism","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/navigating-criticism/index.md","filePath":"garden/guide-to-incrementals/navigating-criticism/index.md"}'),m={name:"garden/guide-to-incrementals/navigating-criticism/index.md"},b=Object.assign(m,{setup(h){const a=n();return(g,p)=>(l(),o("div",null,[c,e("p",null,[r("747 words, ~4 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),u]))}});export{v as __pageData,b as default}; diff --git a/assets/garden_guide-to-incrementals_navigating-criticism_index.md.uvCjn02L.lean.js b/assets/garden_guide-to-incrementals_navigating-criticism_index.md.DivZ76BD.lean.js similarity index 93% rename from assets/garden_guide-to-incrementals_navigating-criticism_index.md.uvCjn02L.lean.js rename to assets/garden_guide-to-incrementals_navigating-criticism_index.md.DivZ76BD.lean.js index f22d7274e..4cde2e404 100644 --- a/assets/garden_guide-to-incrementals_navigating-criticism_index.md.uvCjn02L.lean.js +++ b/assets/garden_guide-to-incrementals_navigating-criticism_index.md.DivZ76BD.lean.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as o,Q as e,K as r,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Guide to Incrementals/Navigating Criticism",-1),d=["innerHTML"],u=s("",12),v=JSON.parse('{"title":"Guide to Incrementals/Navigating Criticism","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/navigating-criticism","title":"Guide to Incrementals/Navigating Criticism","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/navigating-criticism/index.md","filePath":"garden/guide-to-incrementals/navigating-criticism/index.md"}'),m={name:"garden/guide-to-incrementals/navigating-criticism/index.md"},b=Object.assign(m,{setup(h){const a=n();return(g,p)=>(l(),o("div",null,[c,e("p",null,[r("747 words, ~4 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),u]))}});export{v as __pageData,b as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as o,Q as e,K as r,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Guide to Incrementals/Navigating Criticism",-1),d=["innerHTML"],u=s("",12),v=JSON.parse('{"title":"Guide to Incrementals/Navigating Criticism","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/navigating-criticism","title":"Guide to Incrementals/Navigating Criticism","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/navigating-criticism/index.md","filePath":"garden/guide-to-incrementals/navigating-criticism/index.md"}'),m={name:"garden/guide-to-incrementals/navigating-criticism/index.md"},b=Object.assign(m,{setup(h){const a=n();return(g,p)=>(l(),o("div",null,[c,e("p",null,[r("747 words, ~4 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),u]))}});export{v as __pageData,b as default}; diff --git a/assets/garden_guide-to-incrementals_what-is-content_index.md.BEKNdnys.js b/assets/garden_guide-to-incrementals_what-is-content_index.md.DZ5pJU-H.js similarity index 99% rename from assets/garden_guide-to-incrementals_what-is-content_index.md.BEKNdnys.js rename to assets/garden_guide-to-incrementals_what-is-content_index.md.DZ5pJU-H.js index 6ccbeb75e..7014fc7eb 100644 --- a/assets/garden_guide-to-incrementals_what-is-content_index.md.BEKNdnys.js +++ b/assets/garden_guide-to-incrementals_what-is-content_index.md.DZ5pJU-H.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as i,Q as e,K as s,u as t,ag as r,p as h}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Guide to Incrementals/What is Content?",-1),c=["innerHTML"],u=r('
Referenced by:Incremental SocialKronos

If you've been in the incremental games community for any amount of time, you'll quickly find the number one thing players want is content. They want as much of it as possible! The most popular incremental games have tons of content, so they just keep stretching on and on and on, introducing mechanic after mechanic, and players love it. In fact, players seem to value the amount of content over the quality of any specific content. However, there's a bit of a lack of understanding concerning what content is, and I'd like to explore what counts as content, and how we measure it. As a baseline definition, I think "content" can just be described as the parts of the game that engage the player, but to truly understand it we need to contextualize what that means and how it affects the gameplay experience.

To clarify the purpose of this page, my goal is not to get (too) nitpicky or to attack games with "low content". There's nothing wrong with short / low-content games - I'm quite a big fan of those games myself! This is mostly targeted toward those who ask for content and settle for "long" games, and those who want to provide content but want to make sure they're not just artificially inflating the game. Ultimately, I suppose the goal is to just reduce the amount of artificially inflated content for the sake of having a "longer" game.

Interaction

I think it should be a fairly non-controversial opinion that time spent solely waiting should not count towards content. That is not including the time reading various effects or making decisions in your head, but rather time spent waiting for a condition to be met so you can re-engage with the game.

That is not to say games should necessarily try to minimize this time. Plenty of games lead towards more infrequent interaction and still get popular. In fact, these games appeal to many gamers who want to have something to check up on in between bursts of working on some other activity. These games seem to have fallen slightly out of fashion amongst modern incremental games, but they're still fully valid. The point I'm trying to make here is just that this time is not content. As an extreme example, a game with no interactions and just a counter that goes up every second could safely be said to have 0 content beyond the time it takes to understand what's going on. If it has a list of "goals" to hit, then the time understanding those goals and a short time after achieving each one could be considered content, but not the idle times in between.

Let's take a look at the opposite end of the spectrum - interaction that is so frequent as to become mindless. This is any mechanic where you need to spam-click something to progress. This may be a more controversial take, but I do not believe this constitutes content either. It does not engage the player, because each consecutive click blends together and they do not individually change the gameplay experience. That is to say, a single click and 100 clicks are not meaningfully different in terms of engaging the player. I'd go as far as to say clicking 100 times would be actively worse, as it's artificially delaying the next piece of actual content, alongside the issues of accessibility and potentially causing RSI.

Repeatable Purchases

Imagine an entity in a game that you can purchase multiple times, each time it performs the same thing but for a higher cost. These are incredibly common, from the buildings in cookie clicker to the units in swarm sim to the IP and EP multipliers in antimatter dimensions. However, how much content is each specific purchase? Is it content beyond the first purchase? Does it have diminishing returns? What if you are oscillating between two different repeatable purchases? How much content is lost when you automate) away a repeatable purchase?

I don't want to take too harsh a stance against repeatable purchases. They're useful tools and can be used in a myriad of interesting ways. I feel they do become "stale" or less meaningful content over time, and this happens exponentially quickly the more frequently it can be purchased. A classic example that I believe goes too far is the IP/EP multipliers in Antimatter Dimensions. I would go as far as to say they are a chore and do not provide any meaningful content after you've bought them a couple of times. It's a method for inflating numbers (effectively making every OOM a 5x step instead of 10x), that punishes the player progression-wise whenever they forget to max it again, and eventually gets automated away as a reward to the player for making enough progress.

Just to voice the other side of this argument, Acamaeda defended the IP multiplier as giving the player a "good" upgrade every OOM. I can understand that to a point and need to clarify I'm mainly criticizing IP/EP multipliers after they've been introduced for a while. In fact, I would defend the multipliers for a short while after they're introduced using the same logic I would use to defend normal dimensions as repeatable purchases, at least pre-infinity. There's "content" to be had in looking at what dimensions will become affordable next, and then choosing which to buy amongst those. The IP/EP multipliers, early into infinity or eternity respectively, provide another option that gets put into that mental queue of things to buy with each OOM reached - although the optimal order is often quite trivial and not particularly engaging.

The IP/EP multipliers are not the only repeatable purchase in antimatter dimensions I take offense to. The time dimensions are also a series of repeatable purchases, that are all so similar and static that it doesn't take long before you never need to put any thought into buying them, how much you're buying at once, or the order you buy them in - you just press max all and move on. The entire tab could've been just the max all button and it would not have made a difference beyond the start of the eternity layer. The normal dimensions technically have this problem as well, but since you're constantly getting antimatter the order feels like it has a larger impact and it's more meaningful content, right up until they're automated away. Infinity dimensions are a compromise between the two, so I'm highlighting time dimensions here as the most egregious.

Following Instructions

We're getting more and more controversial as we go along! Let's talk about how linear content is not content now (in some circumstances). A trend in incremental games is adding difficulty by adding a web of effects that abstract the true change you can expect from any specific purchase or decision you make. If a game is both linear and sufficiently abstracts the effect of player decisions, then the player will no longer be engaging with the content - they'll simply be clicking on things as they become available. This isn't necessarily a bad thing, as plenty of players don't mind this style of gameplay, but I'd argue once you reach a point where players don't bother reading the effects, those interactions are no longer truly content. Note that unlike the previous qualifiers mentioned, this qualifier is based on the player, and therefore subjective. In effect, it's a spectrum where the more complicated the web of effects becomes, the more likely it is to disengage the player.

This over-complicatedness leading to disengaging the player can also happen from non-linear gameplay. If the web of effects becomes sufficiently complicated and finding the optimal progression route too time-consuming to discover, players will seek out guides from other players who've completed the game. The second they do this, the game effectively becomes linearly following the instructions of the guide and all the above criticisms apply. Similarly to as before, though, this is a spectrum and not everyone will seek out a guide at the same level of difficulty.

Automation

Automation is a staple of the genre, but it has certain implications for the design of the game. Why, when new content is introduced, must the older content be automated away - why is it a chore and it feels rewarding to not have to do it again? Why does the new mechanic have such appeal if we know it too will just be automated away later on, and we'll be happy when that happens? It honestly begs the question of why this framework of introducing content and automating the old content is even enjoyable - and nearly nonexistent in other genres. You're not going to reach a point in a platformer game where they just automate the jumping part - that's the core mechanic! Instead, platformers either add new mechanics that build on the core mechanic or at least re-contextualize the core mechanic. However, in incremental games new content very frequently means replacing older content, as opposed to augmenting it.

Admittedly, the above paragraph ignores the obvious answer that separates incremental games in this regard. These mechanics become chores as their frequency increases. The frequency increases to give a sense of progression, and automation is seen as a reward because it now manages what was becoming unmanageable. The new content then comes in and continues the loop to give a stronger sense of progression. That's all good and a fine justification for automating content instead of building upon the base mechanic. It's also much easier to design, as each layer essentially lets you start over instead of needing to think of ideas that conform to the original core mechanic.

So, what's the problem? Even if this trend is justified and easy to implement, there are some other effects it has on the game design. First off, and this is probably a neutral point, incremental games with this cycle of replacing old mechanics with new ones trend towards more and more abstract and further away from any narrative throughline as they add layers. There are only so many justifications for resetting progress, so if a game wants to have several of these layers they're inevitably going to become generic or increasingly loosely associated with the original content. It's most unfortunate, in my opinion when an interesting or innovative core mechanic gets fully automated once a generic "prestige" layer is unlocked.

A recent example is Really Grass Cutting Incremental, an incremental game about cutting grass (although I'm really criticizing the Roblox game it's based on). Except, it doesn't continue to be about cutting grass. After you buy enough upgrades to increase your grass cutting and level up sufficiently you "prestige", an abstract term that in this case means you reset all your progress to get some currency to buy upgrades that do the same things as the original upgrades, but these won't reset on future prestiges. You'll eventually be able to "crystallize", which means you reset all your progress to get some currency to buy upgrades that do the same things as the original upgrades (and a couple of new ones) and won't reset on future crystallizes. Fine. You'll progress a bit, complete some challenges, and finally get to... grasshop? Grasshopping is this mechanic where you reset all your progress to get some resource that isn't for buying upgrades - this time you just unlock different modifiers on everything based on their amount. You may have gotten the point by now, but there are also "steelie" resets which give you steel for some reason, before unlocking a factory with various machines - none of which are directly tied to cutting grass, and start gathering things like oil and reset for rocket parts and reset to go to space and so on and so on. Throughout all of this there is absolutely no narrative justification or throughline for the direction the game is going, or why cutting grass is still relevant when we're collecting things like rocket parts. I may be going a little hard on GCI, but it is far from alone.

Ending the Game

Incremental games do not often have a planned out narrative or ending,, such that each content update is approached as its own unit of narrative and gameplay. This prevents content updates from wrapping up the game nicely - it always has to leave something open for another content layer; be it another mechanic, reset layer, etc. This cycle will continue until the updates just stop, at which point the game will just have an unsatisfying conclusion that will never get the next thing it was supposed to be leading into. This reminds me of a Leonardo Da Vinci quote about how Art is Never Complete:

Art is never finished, only abandoned. - Leonardo Da Vinci

For what its worth, there are exceptions here (including several of My Projects). I believe this practice is actually fairly reasonable, considering how many incremental game developers are learning game design and programming - keeping the scope small and expanding if it still interests you is a great way to keep learning without letting things like perfectionism or sunk cost fallacies get in the way.

Tips for Developers

If you're a developer, by this point you should have a pretty decent idea of how to create "true" content in your game. Here are some other specific tips I'd suggest:

An upgrade that simply unlocks another upgrade trivially isn't content. However, many games have an upgrade that just unlocks a feature, which then has a wait or other requirements before it can be used. Try to make sure when you unlock a feature, there is immediately something to do with the feature - for example, perhaps give them a small amount of the new currency it unlocks, if applicable.

If you don't have a large web of effects, and can definitively say the impact of a purchase is to multiply the gain of the cost currency by N, and the next purchase costs N times the amount of that same currency, then this purchase effectively made no difference and it may have made more sense to just go directly to the next upgrade. That said, having effects based on things like the number of purchases made will quickly invalidate this tip.

',29),b=JSON.parse('{"title":"Guide to Incrementals/What is Content?","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/what-is-content-","title":"Guide to Incrementals/What is Content?","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/what-is-content/index.md","filePath":"garden/guide-to-incrementals/what-is-content/index.md"}'),m={name:"garden/guide-to-incrementals/what-is-content/index.md"},w=Object.assign(m,{setup(d){const a=o();return(g,p)=>(h(),i("div",null,[l,e("p",null,[s("2272 words, ~12 minute read. "),e("span",{innerHTML:t(n)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),u]))}});export{b as __pageData,w as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as i,Q as e,K as s,u as t,ag as r,p as h}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Guide to Incrementals/What is Content?",-1),c=["innerHTML"],u=r('
Referenced by:Incremental SocialKronos

If you've been in the incremental games community for any amount of time, you'll quickly find the number one thing players want is content. They want as much of it as possible! The most popular incremental games have tons of content, so they just keep stretching on and on and on, introducing mechanic after mechanic, and players love it. In fact, players seem to value the amount of content over the quality of any specific content. However, there's a bit of a lack of understanding concerning what content is, and I'd like to explore what counts as content, and how we measure it. As a baseline definition, I think "content" can just be described as the parts of the game that engage the player, but to truly understand it we need to contextualize what that means and how it affects the gameplay experience.

To clarify the purpose of this page, my goal is not to get (too) nitpicky or to attack games with "low content". There's nothing wrong with short / low-content games - I'm quite a big fan of those games myself! This is mostly targeted toward those who ask for content and settle for "long" games, and those who want to provide content but want to make sure they're not just artificially inflating the game. Ultimately, I suppose the goal is to just reduce the amount of artificially inflated content for the sake of having a "longer" game.

Interaction

I think it should be a fairly non-controversial opinion that time spent solely waiting should not count towards content. That is not including the time reading various effects or making decisions in your head, but rather time spent waiting for a condition to be met so you can re-engage with the game.

That is not to say games should necessarily try to minimize this time. Plenty of games lead towards more infrequent interaction and still get popular. In fact, these games appeal to many gamers who want to have something to check up on in between bursts of working on some other activity. These games seem to have fallen slightly out of fashion amongst modern incremental games, but they're still fully valid. The point I'm trying to make here is just that this time is not content. As an extreme example, a game with no interactions and just a counter that goes up every second could safely be said to have 0 content beyond the time it takes to understand what's going on. If it has a list of "goals" to hit, then the time understanding those goals and a short time after achieving each one could be considered content, but not the idle times in between.

Let's take a look at the opposite end of the spectrum - interaction that is so frequent as to become mindless. This is any mechanic where you need to spam-click something to progress. This may be a more controversial take, but I do not believe this constitutes content either. It does not engage the player, because each consecutive click blends together and they do not individually change the gameplay experience. That is to say, a single click and 100 clicks are not meaningfully different in terms of engaging the player. I'd go as far as to say clicking 100 times would be actively worse, as it's artificially delaying the next piece of actual content, alongside the issues of accessibility and potentially causing RSI.

Repeatable Purchases

Imagine an entity in a game that you can purchase multiple times, each time it performs the same thing but for a higher cost. These are incredibly common, from the buildings in cookie clicker to the units in swarm sim to the IP and EP multipliers in antimatter dimensions. However, how much content is each specific purchase? Is it content beyond the first purchase? Does it have diminishing returns? What if you are oscillating between two different repeatable purchases? How much content is lost when you automate) away a repeatable purchase?

I don't want to take too harsh a stance against repeatable purchases. They're useful tools and can be used in a myriad of interesting ways. I feel they do become "stale" or less meaningful content over time, and this happens exponentially quickly the more frequently it can be purchased. A classic example that I believe goes too far is the IP/EP multipliers in Antimatter Dimensions. I would go as far as to say they are a chore and do not provide any meaningful content after you've bought them a couple of times. It's a method for inflating numbers (effectively making every OOM a 5x step instead of 10x), that punishes the player progression-wise whenever they forget to max it again, and eventually gets automated away as a reward to the player for making enough progress.

Just to voice the other side of this argument, Acamaeda defended the IP multiplier as giving the player a "good" upgrade every OOM. I can understand that to a point and need to clarify I'm mainly criticizing IP/EP multipliers after they've been introduced for a while. In fact, I would defend the multipliers for a short while after they're introduced using the same logic I would use to defend normal dimensions as repeatable purchases, at least pre-infinity. There's "content" to be had in looking at what dimensions will become affordable next, and then choosing which to buy amongst those. The IP/EP multipliers, early into infinity or eternity respectively, provide another option that gets put into that mental queue of things to buy with each OOM reached - although the optimal order is often quite trivial and not particularly engaging.

The IP/EP multipliers are not the only repeatable purchase in antimatter dimensions I take offense to. The time dimensions are also a series of repeatable purchases, that are all so similar and static that it doesn't take long before you never need to put any thought into buying them, how much you're buying at once, or the order you buy them in - you just press max all and move on. The entire tab could've been just the max all button and it would not have made a difference beyond the start of the eternity layer. The normal dimensions technically have this problem as well, but since you're constantly getting antimatter the order feels like it has a larger impact and it's more meaningful content, right up until they're automated away. Infinity dimensions are a compromise between the two, so I'm highlighting time dimensions here as the most egregious.

Following Instructions

We're getting more and more controversial as we go along! Let's talk about how linear content is not content now (in some circumstances). A trend in incremental games is adding difficulty by adding a web of effects that abstract the true change you can expect from any specific purchase or decision you make. If a game is both linear and sufficiently abstracts the effect of player decisions, then the player will no longer be engaging with the content - they'll simply be clicking on things as they become available. This isn't necessarily a bad thing, as plenty of players don't mind this style of gameplay, but I'd argue once you reach a point where players don't bother reading the effects, those interactions are no longer truly content. Note that unlike the previous qualifiers mentioned, this qualifier is based on the player, and therefore subjective. In effect, it's a spectrum where the more complicated the web of effects becomes, the more likely it is to disengage the player.

This over-complicatedness leading to disengaging the player can also happen from non-linear gameplay. If the web of effects becomes sufficiently complicated and finding the optimal progression route too time-consuming to discover, players will seek out guides from other players who've completed the game. The second they do this, the game effectively becomes linearly following the instructions of the guide and all the above criticisms apply. Similarly to as before, though, this is a spectrum and not everyone will seek out a guide at the same level of difficulty.

Automation

Automation is a staple of the genre, but it has certain implications for the design of the game. Why, when new content is introduced, must the older content be automated away - why is it a chore and it feels rewarding to not have to do it again? Why does the new mechanic have such appeal if we know it too will just be automated away later on, and we'll be happy when that happens? It honestly begs the question of why this framework of introducing content and automating the old content is even enjoyable - and nearly nonexistent in other genres. You're not going to reach a point in a platformer game where they just automate the jumping part - that's the core mechanic! Instead, platformers either add new mechanics that build on the core mechanic or at least re-contextualize the core mechanic. However, in incremental games new content very frequently means replacing older content, as opposed to augmenting it.

Admittedly, the above paragraph ignores the obvious answer that separates incremental games in this regard. These mechanics become chores as their frequency increases. The frequency increases to give a sense of progression, and automation is seen as a reward because it now manages what was becoming unmanageable. The new content then comes in and continues the loop to give a stronger sense of progression. That's all good and a fine justification for automating content instead of building upon the base mechanic. It's also much easier to design, as each layer essentially lets you start over instead of needing to think of ideas that conform to the original core mechanic.

So, what's the problem? Even if this trend is justified and easy to implement, there are some other effects it has on the game design. First off, and this is probably a neutral point, incremental games with this cycle of replacing old mechanics with new ones trend towards more and more abstract and further away from any narrative throughline as they add layers. There are only so many justifications for resetting progress, so if a game wants to have several of these layers they're inevitably going to become generic or increasingly loosely associated with the original content. It's most unfortunate, in my opinion when an interesting or innovative core mechanic gets fully automated once a generic "prestige" layer is unlocked.

A recent example is Really Grass Cutting Incremental, an incremental game about cutting grass (although I'm really criticizing the Roblox game it's based on). Except, it doesn't continue to be about cutting grass. After you buy enough upgrades to increase your grass cutting and level up sufficiently you "prestige", an abstract term that in this case means you reset all your progress to get some currency to buy upgrades that do the same things as the original upgrades, but these won't reset on future prestiges. You'll eventually be able to "crystallize", which means you reset all your progress to get some currency to buy upgrades that do the same things as the original upgrades (and a couple of new ones) and won't reset on future crystallizes. Fine. You'll progress a bit, complete some challenges, and finally get to... grasshop? Grasshopping is this mechanic where you reset all your progress to get some resource that isn't for buying upgrades - this time you just unlock different modifiers on everything based on their amount. You may have gotten the point by now, but there are also "steelie" resets which give you steel for some reason, before unlocking a factory with various machines - none of which are directly tied to cutting grass, and start gathering things like oil and reset for rocket parts and reset to go to space and so on and so on. Throughout all of this there is absolutely no narrative justification or throughline for the direction the game is going, or why cutting grass is still relevant when we're collecting things like rocket parts. I may be going a little hard on GCI, but it is far from alone.

Ending the Game

Incremental games do not often have a planned out narrative or ending,, such that each content update is approached as its own unit of narrative and gameplay. This prevents content updates from wrapping up the game nicely - it always has to leave something open for another content layer; be it another mechanic, reset layer, etc. This cycle will continue until the updates just stop, at which point the game will just have an unsatisfying conclusion that will never get the next thing it was supposed to be leading into. This reminds me of a Leonardo Da Vinci quote about how Art is Never Complete:

Art is never finished, only abandoned. - Leonardo Da Vinci

For what its worth, there are exceptions here (including several of My Projects). I believe this practice is actually fairly reasonable, considering how many incremental game developers are learning game design and programming - keeping the scope small and expanding if it still interests you is a great way to keep learning without letting things like perfectionism or sunk cost fallacies get in the way.

Tips for Developers

If you're a developer, by this point you should have a pretty decent idea of how to create "true" content in your game. Here are some other specific tips I'd suggest:

An upgrade that simply unlocks another upgrade trivially isn't content. However, many games have an upgrade that just unlocks a feature, which then has a wait or other requirements before it can be used. Try to make sure when you unlock a feature, there is immediately something to do with the feature - for example, perhaps give them a small amount of the new currency it unlocks, if applicable.

If you don't have a large web of effects, and can definitively say the impact of a purchase is to multiply the gain of the cost currency by N, and the next purchase costs N times the amount of that same currency, then this purchase effectively made no difference and it may have made more sense to just go directly to the next upgrade. That said, having effects based on things like the number of purchases made will quickly invalidate this tip.

',29),b=JSON.parse('{"title":"Guide to Incrementals/What is Content?","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/what-is-content-","title":"Guide to Incrementals/What is Content?","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/what-is-content/index.md","filePath":"garden/guide-to-incrementals/what-is-content/index.md"}'),m={name:"garden/guide-to-incrementals/what-is-content/index.md"},w=Object.assign(m,{setup(d){const a=o();return(g,p)=>(h(),i("div",null,[l,e("p",null,[s("2272 words, ~12 minute read. "),e("span",{innerHTML:t(n)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),u]))}});export{b as __pageData,w as default}; diff --git a/assets/garden_guide-to-incrementals_what-is-content_index.md.BEKNdnys.lean.js b/assets/garden_guide-to-incrementals_what-is-content_index.md.DZ5pJU-H.lean.js similarity index 93% rename from assets/garden_guide-to-incrementals_what-is-content_index.md.BEKNdnys.lean.js rename to assets/garden_guide-to-incrementals_what-is-content_index.md.DZ5pJU-H.lean.js index bc29029ed..03cc30e68 100644 --- a/assets/garden_guide-to-incrementals_what-is-content_index.md.BEKNdnys.lean.js +++ b/assets/garden_guide-to-incrementals_what-is-content_index.md.DZ5pJU-H.lean.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as i,Q as e,K as s,u as t,ag as r,p as h}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Guide to Incrementals/What is Content?",-1),c=["innerHTML"],u=r("",29),b=JSON.parse('{"title":"Guide to Incrementals/What is Content?","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/what-is-content-","title":"Guide to Incrementals/What is Content?","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/what-is-content/index.md","filePath":"garden/guide-to-incrementals/what-is-content/index.md"}'),m={name:"garden/guide-to-incrementals/what-is-content/index.md"},w=Object.assign(m,{setup(d){const a=o();return(g,p)=>(h(),i("div",null,[l,e("p",null,[s("2272 words, ~12 minute read. "),e("span",{innerHTML:t(n)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),u]))}});export{b as __pageData,w as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as i,Q as e,K as s,u as t,ag as r,p as h}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Guide to Incrementals/What is Content?",-1),c=["innerHTML"],u=r("",29),b=JSON.parse('{"title":"Guide to Incrementals/What is Content?","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/what-is-content-","title":"Guide to Incrementals/What is Content?","prev":false,"next":false},"headers":[],"relativePath":"garden/guide-to-incrementals/what-is-content/index.md","filePath":"garden/guide-to-incrementals/what-is-content/index.md"}'),m={name:"garden/guide-to-incrementals/what-is-content/index.md"},w=Object.assign(m,{setup(d){const a=o();return(g,p)=>(h(),i("div",null,[l,e("p",null,[s("2272 words, ~12 minute read. "),e("span",{innerHTML:t(n)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),u]))}});export{b as __pageData,w as default}; diff --git a/assets/garden_imperialism_index.md.D1389wsm.js b/assets/garden_imperialism_index.md.CshuexhP.js similarity index 99% rename from assets/garden_imperialism_index.md.D1389wsm.js rename to assets/garden_imperialism_index.md.CshuexhP.js index 42605739d..08abf67d9 100644 --- a/assets/garden_imperialism_index.md.D1389wsm.js +++ b/assets/garden_imperialism_index.md.CshuexhP.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as r,q as o,Q as e,K as n,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Imperialism",-1),c=["innerHTML"],d=s('
Referenced by:LeftismMy Political Beliefs

Imperialism refers to how, after all the survivable land in the world was claimed by various countries (as part of colonialism), a country - or empire - must spread its influence over new territory at cost of existing influences over that territory. Typically this has meant land being transferred, either militarily or diplomatically.

Imperialism and Capitalism

Lenin wrote an influential pamphlet over his interpretation of imperialism, called "Imperialism, the Highest Stage of Capitalism". He argued imperialism was inextricably linked with capitalism, and that the driving force of imperialism was corporations gaining control over natural resources to use for profit, and to improve their position relative to opposing powers. An imperialist war, such as the ones the US has fought in the Middle East, serve both the interests of US oil companies as well as the US itself for its position relative to other imperialist powers. This view has been supported by modern leftist scholars like Michael Parenti in his book Face of Imperialism: Responsibility-Taking in the Political World.

In effect, imperialism has been used to delay resolving the contradiction between the need to expand and the physical limits of the globe. This contradiction cannot be fully resolved under a capitalist system, which requires the need to expand infinitely. Therefore, fighting imperialism means fighting capitalism. Removing power from corporations and banks largely nullifies the reasons for imperialism and is the best path towards global peace.

US Imperialism

The size of the US empire is not obvious just by looking at a map of the world, due to its reliance on economic influence and soft power. The US also imperializes through its remaining colonies, proxy wars, and foreign military bases. Second thought has a good introductory video on how significant some of those influences are in How The US Took Over The World.

A lot of these conflicts abroad are done in the open, such as the conflicts part of the war on terror. In this case the government needs to justify to its citizens going to war, which you'll typically see happen regardless of who's in charge. This is a process called manufactured consent, as described by Herman and Chomsky in Manufacturing Consent: The Political Economy of the Mass Media, although it is not perfect and the US has a history of anti-war protest movements. The vietnam war was our first televised war and had anti war protests even escalate into riots. Today through social media the impact of war is more accessible than ever before, and the Israel-Palestine conflict has had one of the largest anti-war movements yet, although still not as large as Vietnam.

While there are several imperialist powers in the world, the US is a particularly influential one that I, as an American citizen, have the most personal interest in stopping. I believe if the US moved towards socialism the overall influence of capitalism in the world would diminish so thoroughly that it would only further decline into non-existence. This would affect not only the prosperity of the world but save many lives as well: Western imperialism has caused 50-55 million deaths since WW2 as claimed by Andre Vltchek in On western terror, and US-backed conflicts show no sign of stopping so long as capitalist interests remain.

Impact of Imperialism on the Development of the Global South

The global south refers to a collection of countries that are under-developed compared to the "global north", and have historically been victims of colonialism and imperialism. Today, the global south makes up 90% of global labor but only receives 21% of globally produced value, according to Jason Hickel et al in Unequal exchange of labour in the world economy. Jason has previously calculated that the global north extracted $242 trillion in value from the global south between 1990 and 2015 alone, despite only returning 1/30th of that in the form of foreign aid, in Imperialist appropriation in the world economy: Drain from the global South through unequal exchange, 1990–2015.

It's worth noting that Hickel is discussing all of the global north, not just the US, but US corporations make heavy use of exploitation by underpaying workers without any form of representation for the exploited or assistance in modernizing these countries ("catching up" developmentally). They allow corporations to act with essentially impunity, not enforcing any form of ethics or ensuring the development of the countries they're getting labor and resources from isn't stagnant. Earth Rights International reported on how Nestle and Cargill were sued for using child slavery in West Africa and after 15 years of legal process finally decided the US-based corporations were not liable for these human rights violations.

In contrast to the US, China has the Belt and Road Initiative started in 2013 where the state itself will lend money to improve the infrastructure development of these countries (and some in the global north as well), and allow for fully free trade (no tariffs) from the particularly underdeveloped. It faced initial backlash, which China responded to by improving their reporting standards and transparency with the countries they've signed contracts with, as described in China’s response to Belt and Road backlash. The initiative has continued to expand since then, and now has contracts with around 150 countries as listed by the Green Finance & Development Center in Countries of the Belt and Road Initiative (BRI), and accounts for around 20 trillion USD of trade, as reported by China in 2023 in a document called Vision and Actions for High-Quality Belt and Road Cooperation: Brighter Prospects for the Next Decade (cited via an English summary). The BRI has remained controversial within the west, but sentiment seems negative overall. Since 2020 various western publications have labeled the program "debt-trap diplomacy". There are some genuine concerns - China's reluctance to forgive debt and a lack of oversight on how the lent funds are used top amongst them - but I believe they're being exaggerated due to western's biases towards capitalist interests and general sinophobia. I'd link a specific article but there are so many that I'll actually just recommend looking through the wikipedia article for the Belt and Road Initiative which includes various articles from a lot of sources both in favor of and in opposition to the initiative. It has literally hundreds of citations, one of the most well-cited articles I've seen. I get the overall impression that the BRI is arguably more cooperative than exploitative in nature compared to the US strategy, and the countries themselves seem to view the initiative favorably, considering 3/4 of all UN recognized countries are already part of the initiative, with very few choosing not to renew contracts.

Further Reading

Jason Hickel made a very digestible explanation over the importance of liberating Palestine in the fight against imperialism, which was clipped into Why a Liberated Palestine Threatens Global Capitalism.

',16),w=JSON.parse('{"title":"Imperialism","description":"","frontmatter":{"alias":"Imperialist","public":"true","slug":"imperialism","title":"Imperialism","prev":false,"next":false},"headers":[],"relativePath":"garden/imperialism/index.md","filePath":"garden/imperialism/index.md"}'),p={name:"garden/imperialism/index.md"},y=Object.assign(p,{setup(m){const a=r();return(f,u)=>(l(),o("div",null,[h,e("p",null,[n("770 words, ~4 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),d]))}});export{w as __pageData,y as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as r,q as o,Q as e,K as n,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Imperialism",-1),c=["innerHTML"],d=s('
Referenced by:LeftismMy Political Beliefs

Imperialism refers to how, after all the survivable land in the world was claimed by various countries (as part of colonialism), a country - or empire - must spread its influence over new territory at cost of existing influences over that territory. Typically this has meant land being transferred, either militarily or diplomatically.

Imperialism and Capitalism

Lenin wrote an influential pamphlet over his interpretation of imperialism, called "Imperialism, the Highest Stage of Capitalism". He argued imperialism was inextricably linked with capitalism, and that the driving force of imperialism was corporations gaining control over natural resources to use for profit, and to improve their position relative to opposing powers. An imperialist war, such as the ones the US has fought in the Middle East, serve both the interests of US oil companies as well as the US itself for its position relative to other imperialist powers. This view has been supported by modern leftist scholars like Michael Parenti in his book Face of Imperialism: Responsibility-Taking in the Political World.

In effect, imperialism has been used to delay resolving the contradiction between the need to expand and the physical limits of the globe. This contradiction cannot be fully resolved under a capitalist system, which requires the need to expand infinitely. Therefore, fighting imperialism means fighting capitalism. Removing power from corporations and banks largely nullifies the reasons for imperialism and is the best path towards global peace.

US Imperialism

The size of the US empire is not obvious just by looking at a map of the world, due to its reliance on economic influence and soft power. The US also imperializes through its remaining colonies, proxy wars, and foreign military bases. Second thought has a good introductory video on how significant some of those influences are in How The US Took Over The World.

A lot of these conflicts abroad are done in the open, such as the conflicts part of the war on terror. In this case the government needs to justify to its citizens going to war, which you'll typically see happen regardless of who's in charge. This is a process called manufactured consent, as described by Herman and Chomsky in Manufacturing Consent: The Political Economy of the Mass Media, although it is not perfect and the US has a history of anti-war protest movements. The vietnam war was our first televised war and had anti war protests even escalate into riots. Today through social media the impact of war is more accessible than ever before, and the Israel-Palestine conflict has had one of the largest anti-war movements yet, although still not as large as Vietnam.

While there are several imperialist powers in the world, the US is a particularly influential one that I, as an American citizen, have the most personal interest in stopping. I believe if the US moved towards socialism the overall influence of capitalism in the world would diminish so thoroughly that it would only further decline into non-existence. This would affect not only the prosperity of the world but save many lives as well: Western imperialism has caused 50-55 million deaths since WW2 as claimed by Andre Vltchek in On western terror, and US-backed conflicts show no sign of stopping so long as capitalist interests remain.

Impact of Imperialism on the Development of the Global South

The global south refers to a collection of countries that are under-developed compared to the "global north", and have historically been victims of colonialism and imperialism. Today, the global south makes up 90% of global labor but only receives 21% of globally produced value, according to Jason Hickel et al in Unequal exchange of labour in the world economy. Jason has previously calculated that the global north extracted $242 trillion in value from the global south between 1990 and 2015 alone, despite only returning 1/30th of that in the form of foreign aid, in Imperialist appropriation in the world economy: Drain from the global South through unequal exchange, 1990–2015.

It's worth noting that Hickel is discussing all of the global north, not just the US, but US corporations make heavy use of exploitation by underpaying workers without any form of representation for the exploited or assistance in modernizing these countries ("catching up" developmentally). They allow corporations to act with essentially impunity, not enforcing any form of ethics or ensuring the development of the countries they're getting labor and resources from isn't stagnant. Earth Rights International reported on how Nestle and Cargill were sued for using child slavery in West Africa and after 15 years of legal process finally decided the US-based corporations were not liable for these human rights violations.

In contrast to the US, China has the Belt and Road Initiative started in 2013 where the state itself will lend money to improve the infrastructure development of these countries (and some in the global north as well), and allow for fully free trade (no tariffs) from the particularly underdeveloped. It faced initial backlash, which China responded to by improving their reporting standards and transparency with the countries they've signed contracts with, as described in China’s response to Belt and Road backlash. The initiative has continued to expand since then, and now has contracts with around 150 countries as listed by the Green Finance & Development Center in Countries of the Belt and Road Initiative (BRI), and accounts for around 20 trillion USD of trade, as reported by China in 2023 in a document called Vision and Actions for High-Quality Belt and Road Cooperation: Brighter Prospects for the Next Decade (cited via an English summary). The BRI has remained controversial within the west, but sentiment seems negative overall. Since 2020 various western publications have labeled the program "debt-trap diplomacy". There are some genuine concerns - China's reluctance to forgive debt and a lack of oversight on how the lent funds are used top amongst them - but I believe they're being exaggerated due to western's biases towards capitalist interests and general sinophobia. I'd link a specific article but there are so many that I'll actually just recommend looking through the wikipedia article for the Belt and Road Initiative which includes various articles from a lot of sources both in favor of and in opposition to the initiative. It has literally hundreds of citations, one of the most well-cited articles I've seen. I get the overall impression that the BRI is arguably more cooperative than exploitative in nature compared to the US strategy, and the countries themselves seem to view the initiative favorably, considering 3/4 of all UN recognized countries are already part of the initiative, with very few choosing not to renew contracts.

Further Reading

Jason Hickel made a very digestible explanation over the importance of liberating Palestine in the fight against imperialism, which was clipped into Why a Liberated Palestine Threatens Global Capitalism.

',16),w=JSON.parse('{"title":"Imperialism","description":"","frontmatter":{"alias":"Imperialist","public":"true","slug":"imperialism","title":"Imperialism","prev":false,"next":false},"headers":[],"relativePath":"garden/imperialism/index.md","filePath":"garden/imperialism/index.md"}'),p={name:"garden/imperialism/index.md"},y=Object.assign(p,{setup(m){const a=r();return(f,u)=>(l(),o("div",null,[h,e("p",null,[n("770 words, ~4 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),d]))}});export{w as __pageData,y as default}; diff --git a/assets/garden_imperialism_index.md.D1389wsm.lean.js b/assets/garden_imperialism_index.md.CshuexhP.lean.js similarity index 91% rename from assets/garden_imperialism_index.md.D1389wsm.lean.js rename to assets/garden_imperialism_index.md.CshuexhP.lean.js index ec5046952..3883867da 100644 --- a/assets/garden_imperialism_index.md.D1389wsm.lean.js +++ b/assets/garden_imperialism_index.md.CshuexhP.lean.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as r,q as o,Q as e,K as n,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Imperialism",-1),c=["innerHTML"],d=s("",16),w=JSON.parse('{"title":"Imperialism","description":"","frontmatter":{"alias":"Imperialist","public":"true","slug":"imperialism","title":"Imperialism","prev":false,"next":false},"headers":[],"relativePath":"garden/imperialism/index.md","filePath":"garden/imperialism/index.md"}'),p={name:"garden/imperialism/index.md"},y=Object.assign(p,{setup(m){const a=r();return(f,u)=>(l(),o("div",null,[h,e("p",null,[n("770 words, ~4 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),d]))}});export{w as __pageData,y as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as r,q as o,Q as e,K as n,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Imperialism",-1),c=["innerHTML"],d=s("",16),w=JSON.parse('{"title":"Imperialism","description":"","frontmatter":{"alias":"Imperialist","public":"true","slug":"imperialism","title":"Imperialism","prev":false,"next":false},"headers":[],"relativePath":"garden/imperialism/index.md","filePath":"garden/imperialism/index.md"}'),p={name:"garden/imperialism/index.md"},y=Object.assign(p,{setup(m){const a=r();return(f,u)=>(l(),o("div",null,[h,e("p",null,[n("770 words, ~4 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),d]))}});export{w as __pageData,y as default}; diff --git a/assets/garden_incremental-social_index.md.Dr5ZrztL.js b/assets/garden_incremental-social_index.md.BzhAzaXZ.js similarity index 97% rename from assets/garden_incremental-social_index.md.Dr5ZrztL.js rename to assets/garden_incremental-social_index.md.BzhAzaXZ.js index 77c466ab2..0f10dbe52 100644 --- a/assets/garden_incremental-social_index.md.Dr5ZrztL.js +++ b/assets/garden_incremental-social_index.md.BzhAzaXZ.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as r,q as s,Q as e,K as i,u as a,ag as o,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Incremental Social",-1),c=["innerHTML"],m=o('
Referenced by:My Personal Website/nowWebrings
Tags:My Projects

Incremental Social is a Fediverse website hosted by me! It was made under the motivation of the fediverse working best when split up into websites that are specialized for specific communities - and in this case, Incremental Social was made and designed explicitly for the incremental games community! Most notably, it hosts an instance of Mbin, Forgejo, and Synapse (and Cinny). Mbin allows it to read and write both reddit-style threads and twitter-style posts, and forgejo allows developers to host their web games. Synapse allows the community to chat in a more synchronous fashion than Mbin.

In the future I plan on having the platform also generate a keypair to allow the user to use this account as their Decentralized Identity on the Agentic Fediverse.

With all these platforms, there will be a goal to support migrating identities elsewhere, so users are not locked in to our platform. Unfortunately a lot of these protocols don't support migration, or not well, so this is going to be a long-term goal.

',6),y=JSON.parse('{"title":"Incremental Social","description":"","frontmatter":{"public":"true","slug":"incremental-social","tags":["My Projects"],"title":"Incremental Social","prev":false,"next":false},"headers":[],"relativePath":"garden/incremental-social/index.md","filePath":"garden/incremental-social/index.md"}'),h={name:"garden/incremental-social/index.md"},b=Object.assign(h,{setup(p){const t=r();return(g,f)=>(l(),s("div",null,[d,e("p",null,[i("114 words, ~1 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),m]))}});export{y as __pageData,b as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as r,q as s,Q as e,K as i,u as a,ag as o,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Incremental Social",-1),c=["innerHTML"],m=o('
Referenced by:My Personal Website/nowWebrings
Tags:My Projects

Incremental Social is a Fediverse website hosted by me! It was made under the motivation of the fediverse working best when split up into websites that are specialized for specific communities - and in this case, Incremental Social was made and designed explicitly for the incremental games community! Most notably, it hosts an instance of Mbin, Forgejo, and Synapse (and Cinny). Mbin allows it to read and write both reddit-style threads and twitter-style posts, and forgejo allows developers to host their web games. Synapse allows the community to chat in a more synchronous fashion than Mbin.

In the future I plan on having the platform also generate a keypair to allow the user to use this account as their Decentralized Identity on the Agentic Fediverse.

With all these platforms, there will be a goal to support migrating identities elsewhere, so users are not locked in to our platform. Unfortunately a lot of these protocols don't support migration, or not well, so this is going to be a long-term goal.

',6),y=JSON.parse('{"title":"Incremental Social","description":"","frontmatter":{"public":"true","slug":"incremental-social","tags":["My Projects"],"title":"Incremental Social","prev":false,"next":false},"headers":[],"relativePath":"garden/incremental-social/index.md","filePath":"garden/incremental-social/index.md"}'),h={name:"garden/incremental-social/index.md"},b=Object.assign(h,{setup(p){const t=r();return(g,f)=>(l(),s("div",null,[d,e("p",null,[i("114 words, ~1 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),m]))}});export{y as __pageData,b as default}; diff --git a/assets/garden_incremental-social_index.md.Dr5ZrztL.lean.js b/assets/garden_incremental-social_index.md.BzhAzaXZ.lean.js similarity index 92% rename from assets/garden_incremental-social_index.md.Dr5ZrztL.lean.js rename to assets/garden_incremental-social_index.md.BzhAzaXZ.lean.js index 9ce670773..c3f46982d 100644 --- a/assets/garden_incremental-social_index.md.Dr5ZrztL.lean.js +++ b/assets/garden_incremental-social_index.md.BzhAzaXZ.lean.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as r,q as s,Q as e,K as i,u as a,ag as o,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Incremental Social",-1),c=["innerHTML"],m=o("",6),y=JSON.parse('{"title":"Incremental Social","description":"","frontmatter":{"public":"true","slug":"incremental-social","tags":["My Projects"],"title":"Incremental Social","prev":false,"next":false},"headers":[],"relativePath":"garden/incremental-social/index.md","filePath":"garden/incremental-social/index.md"}'),h={name:"garden/incremental-social/index.md"},b=Object.assign(h,{setup(p){const t=r();return(g,f)=>(l(),s("div",null,[d,e("p",null,[i("114 words, ~1 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),m]))}});export{y as __pageData,b as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as r,q as s,Q as e,K as i,u as a,ag as o,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Incremental Social",-1),c=["innerHTML"],m=o("",6),y=JSON.parse('{"title":"Incremental Social","description":"","frontmatter":{"public":"true","slug":"incremental-social","tags":["My Projects"],"title":"Incremental Social","prev":false,"next":false},"headers":[],"relativePath":"garden/incremental-social/index.md","filePath":"garden/incremental-social/index.md"}'),h={name:"garden/incremental-social/index.md"},b=Object.assign(h,{setup(p){const t=r();return(g,f)=>(l(),s("div",null,[d,e("p",null,[i("114 words, ~1 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),m]))}});export{y as __pageData,b as default}; diff --git a/assets/garden_individualism_index.md.ynjLdsuX.js b/assets/garden_individualism_index.md.BpsGeaNn.js similarity index 97% rename from assets/garden_individualism_index.md.ynjLdsuX.js rename to assets/garden_individualism_index.md.BpsGeaNn.js index da671f661..b22bdecd2 100644 --- a/assets/garden_individualism_index.md.ynjLdsuX.js +++ b/assets/garden_individualism_index.md.BpsGeaNn.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as s,Q as e,K as r,u as a,ag as o,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Individualism",-1),m=["innerHTML"],u=o('
Referenced by:AnarchismLocal CommunitiesNeoliberalism

Individualism is a Neoliberal value system centered around independence and self sufficiency. It argues for taking care of oneself before others, and that it's wrong for people to be forced to take care of others before their selves, i.e. via wealth redistribution. This value system is antithetical to the Anarchist values of community and mutual aid. I personally am against individualism and see it as against humans nature of cooperation. We're a social people and have for our entire existence relied upon each other.

As a personal anecdote, I'm a recent parent and the whole "it takes a village" adage makes a lot of sense, and has made me hyper aware of how individualism has made it very hard to raise a kid these days. There's no 3 generations living in a house anymore, and suburbs are spread out and isolating, preventing strong Local Communities from forming. To sum up, the "village" doesn't exist anymore.

Hyper individualism is a modern invention, not a "good ole traditional value" we should all aspire to. It was explicitly created by capitalist values, and replaced pre-existing value systems that prioritized co-operation.

',5),_=JSON.parse('{"title":"Individualism","description":"","frontmatter":{"public":"true","slug":"individualism","title":"Individualism","prev":false,"next":false},"headers":[],"relativePath":"garden/individualism/index.md","filePath":"garden/individualism/index.md"}'),c={name:"garden/individualism/index.md"},y=Object.assign(c,{setup(p){const i=n();return(h,f)=>(d(),s("div",null,[l,e("p",null,[r("195 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(i).page.value.relativePath}`]},null,8,m)]),u]))}});export{_ as __pageData,y as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as s,Q as e,K as r,u as a,ag as o,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Individualism",-1),m=["innerHTML"],u=o('
Referenced by:AnarchismLocal CommunitiesNeoliberalism

Individualism is a Neoliberal value system centered around independence and self sufficiency. It argues for taking care of oneself before others, and that it's wrong for people to be forced to take care of others before their selves, i.e. via wealth redistribution. This value system is antithetical to the Anarchist values of community and mutual aid. I personally am against individualism and see it as against humans nature of cooperation. We're a social people and have for our entire existence relied upon each other.

As a personal anecdote, I'm a recent parent and the whole "it takes a village" adage makes a lot of sense, and has made me hyper aware of how individualism has made it very hard to raise a kid these days. There's no 3 generations living in a house anymore, and suburbs are spread out and isolating, preventing strong Local Communities from forming. To sum up, the "village" doesn't exist anymore.

Hyper individualism is a modern invention, not a "good ole traditional value" we should all aspire to. It was explicitly created by capitalist values, and replaced pre-existing value systems that prioritized co-operation.

',5),_=JSON.parse('{"title":"Individualism","description":"","frontmatter":{"public":"true","slug":"individualism","title":"Individualism","prev":false,"next":false},"headers":[],"relativePath":"garden/individualism/index.md","filePath":"garden/individualism/index.md"}'),c={name:"garden/individualism/index.md"},y=Object.assign(c,{setup(p){const i=n();return(h,f)=>(d(),s("div",null,[l,e("p",null,[r("195 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(i).page.value.relativePath}`]},null,8,m)]),u]))}});export{_ as __pageData,y as default}; diff --git a/assets/garden_individualism_index.md.ynjLdsuX.lean.js b/assets/garden_individualism_index.md.BpsGeaNn.lean.js similarity index 91% rename from assets/garden_individualism_index.md.ynjLdsuX.lean.js rename to assets/garden_individualism_index.md.BpsGeaNn.lean.js index 3ffcea9d0..5e3e34a30 100644 --- a/assets/garden_individualism_index.md.ynjLdsuX.lean.js +++ b/assets/garden_individualism_index.md.BpsGeaNn.lean.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as s,Q as e,K as r,u as a,ag as o,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Individualism",-1),m=["innerHTML"],u=o("",5),_=JSON.parse('{"title":"Individualism","description":"","frontmatter":{"public":"true","slug":"individualism","title":"Individualism","prev":false,"next":false},"headers":[],"relativePath":"garden/individualism/index.md","filePath":"garden/individualism/index.md"}'),c={name:"garden/individualism/index.md"},y=Object.assign(c,{setup(p){const i=n();return(h,f)=>(d(),s("div",null,[l,e("p",null,[r("195 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(i).page.value.relativePath}`]},null,8,m)]),u]))}});export{_ as __pageData,y as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as s,Q as e,K as r,u as a,ag as o,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Individualism",-1),m=["innerHTML"],u=o("",5),_=JSON.parse('{"title":"Individualism","description":"","frontmatter":{"public":"true","slug":"individualism","title":"Individualism","prev":false,"next":false},"headers":[],"relativePath":"garden/individualism/index.md","filePath":"garden/individualism/index.md"}'),c={name:"garden/individualism/index.md"},y=Object.assign(c,{setup(p){const i=n();return(h,f)=>(d(),s("div",null,[l,e("p",null,[r("195 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(i).page.value.relativePath}`]},null,8,m)]),u]))}});export{_ as __pageData,y as default}; diff --git a/assets/garden_ivy-road_index.md.CnA7kCGP.js b/assets/garden_ivy-road_index.md.DZ7vqlGJ.js similarity index 94% rename from assets/garden_ivy-road_index.md.CnA7kCGP.js rename to assets/garden_ivy-road_index.md.DZ7vqlGJ.js index c0c920700..fadb61ac5 100644 --- a/assets/garden_ivy-road_index.md.CnA7kCGP.js +++ b/assets/garden_ivy-road_index.md.DZ7vqlGJ.js @@ -1 +1 @@ -import{d}from"./chunks/git.data.D-Ga3RhB.js";import{M as t,q as n,Q as e,K as s,u as a,ag as i,p as o}from"./chunks/framework.Sr2_9k8k.js";const _=e("h1",{class:"p-name"},"Ivy Road",-1),l=["innerHTML"],m=i('
Referenced by:Davey WredenWanderstop
Tags:Davey Wreden

Ivy Road is a indie game studio created by Davey Wreden, Karla Kimonja, and C418

',4),g=JSON.parse('{"title":"Ivy Road","description":"","frontmatter":{"public":"true","slug":"ivy-road","tags":["Davey Wreden"],"title":"Ivy Road","prev":false,"next":false},"headers":[],"relativePath":"garden/ivy-road/index.md","filePath":"garden/ivy-road/index.md"}'),c={name:"garden/ivy-road/index.md"},h=Object.assign(c,{setup(p){const r=t();return(u,y)=>(o(),n("div",null,[_,e("p",null,[s("6 words, ~0 minute read. "),e("span",{innerHTML:a(d)[`site/${a(r).page.value.relativePath}`]},null,8,l)]),m]))}});export{g as __pageData,h as default}; +import{d}from"./chunks/git.data.BcrWSzMU.js";import{M as t,q as n,Q as e,K as s,u as a,ag as i,p as o}from"./chunks/framework.Sr2_9k8k.js";const _=e("h1",{class:"p-name"},"Ivy Road",-1),l=["innerHTML"],m=i('
Referenced by:Davey WredenWanderstop
Tags:Davey Wreden

Ivy Road is a indie game studio created by Davey Wreden, Karla Kimonja, and C418

',4),g=JSON.parse('{"title":"Ivy Road","description":"","frontmatter":{"public":"true","slug":"ivy-road","tags":["Davey Wreden"],"title":"Ivy Road","prev":false,"next":false},"headers":[],"relativePath":"garden/ivy-road/index.md","filePath":"garden/ivy-road/index.md"}'),c={name:"garden/ivy-road/index.md"},h=Object.assign(c,{setup(p){const r=t();return(u,y)=>(o(),n("div",null,[_,e("p",null,[s("6 words, ~0 minute read. "),e("span",{innerHTML:a(d)[`site/${a(r).page.value.relativePath}`]},null,8,l)]),m]))}});export{g as __pageData,h as default}; diff --git a/assets/garden_ivy-road_index.md.CnA7kCGP.lean.js b/assets/garden_ivy-road_index.md.DZ7vqlGJ.lean.js similarity index 91% rename from assets/garden_ivy-road_index.md.CnA7kCGP.lean.js rename to assets/garden_ivy-road_index.md.DZ7vqlGJ.lean.js index c2dfb98b0..60b0598ef 100644 --- a/assets/garden_ivy-road_index.md.CnA7kCGP.lean.js +++ b/assets/garden_ivy-road_index.md.DZ7vqlGJ.lean.js @@ -1 +1 @@ -import{d}from"./chunks/git.data.D-Ga3RhB.js";import{M as t,q as n,Q as e,K as s,u as a,ag as i,p as o}from"./chunks/framework.Sr2_9k8k.js";const _=e("h1",{class:"p-name"},"Ivy Road",-1),l=["innerHTML"],m=i("",4),g=JSON.parse('{"title":"Ivy Road","description":"","frontmatter":{"public":"true","slug":"ivy-road","tags":["Davey Wreden"],"title":"Ivy Road","prev":false,"next":false},"headers":[],"relativePath":"garden/ivy-road/index.md","filePath":"garden/ivy-road/index.md"}'),c={name:"garden/ivy-road/index.md"},h=Object.assign(c,{setup(p){const r=t();return(u,y)=>(o(),n("div",null,[_,e("p",null,[s("6 words, ~0 minute read. "),e("span",{innerHTML:a(d)[`site/${a(r).page.value.relativePath}`]},null,8,l)]),m]))}});export{g as __pageData,h as default}; +import{d}from"./chunks/git.data.BcrWSzMU.js";import{M as t,q as n,Q as e,K as s,u as a,ag as i,p as o}from"./chunks/framework.Sr2_9k8k.js";const _=e("h1",{class:"p-name"},"Ivy Road",-1),l=["innerHTML"],m=i("",4),g=JSON.parse('{"title":"Ivy Road","description":"","frontmatter":{"public":"true","slug":"ivy-road","tags":["Davey Wreden"],"title":"Ivy Road","prev":false,"next":false},"headers":[],"relativePath":"garden/ivy-road/index.md","filePath":"garden/ivy-road/index.md"}'),c={name:"garden/ivy-road/index.md"},h=Object.assign(c,{setup(p){const r=t();return(u,y)=>(o(),n("div",null,[_,e("p",null,[s("6 words, ~0 minute read. "),e("span",{innerHTML:a(d)[`site/${a(r).page.value.relativePath}`]},null,8,l)]),m]))}});export{g as __pageData,h as default}; diff --git a/assets/garden_kronos_index.md.BX3T3aQP.js b/assets/garden_kronos_index.md.dlLMxxFW.js similarity index 95% rename from assets/garden_kronos_index.md.BX3T3aQP.js rename to assets/garden_kronos_index.md.dlLMxxFW.js index 4c7722ba3..fb6e840d3 100644 --- a/assets/garden_kronos_index.md.BX3T3aQP.js +++ b/assets/garden_kronos_index.md.dlLMxxFW.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as s,Q as e,K as o,u as a,ag as i,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Kronos",-1),p=["innerHTML"],m=i('
Referenced by:/nowV-ecs
Tags:My ProjectsProfectus

My largest and most ambitious incremental game I've ever made

  • A magnum opus, of sorts ;P

Still in development, and will be for a long time. I have full intention of completing it, however

An older version, that is built in The Modding Tree, only has the gameplay, and only goes up to Chapter 2, can be played here

',7),y=JSON.parse('{"title":"Kronos","description":"","frontmatter":{"public":"true","slug":"kronos","tags":["My Projects","Profectus"],"title":"Kronos","prev":false,"next":false},"headers":[],"relativePath":"garden/kronos/index.md","filePath":"garden/kronos/index.md"}'),c={name:"garden/kronos/index.md"},v=Object.assign(c,{setup(u){const t=n();return(_,h)=>(l(),s("div",null,[d,e("p",null,[o("60 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,p)]),m]))}});export{y as __pageData,v as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as s,Q as e,K as o,u as a,ag as i,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Kronos",-1),p=["innerHTML"],m=i('
Referenced by:/nowV-ecs
Tags:My ProjectsProfectus

My largest and most ambitious incremental game I've ever made

  • A magnum opus, of sorts ;P

Still in development, and will be for a long time. I have full intention of completing it, however

An older version, that is built in The Modding Tree, only has the gameplay, and only goes up to Chapter 2, can be played here

',7),y=JSON.parse('{"title":"Kronos","description":"","frontmatter":{"public":"true","slug":"kronos","tags":["My Projects","Profectus"],"title":"Kronos","prev":false,"next":false},"headers":[],"relativePath":"garden/kronos/index.md","filePath":"garden/kronos/index.md"}'),c={name:"garden/kronos/index.md"},v=Object.assign(c,{setup(u){const t=n();return(_,h)=>(l(),s("div",null,[d,e("p",null,[o("60 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,p)]),m]))}});export{y as __pageData,v as default}; diff --git a/assets/garden_kronos_index.md.BX3T3aQP.lean.js b/assets/garden_kronos_index.md.dlLMxxFW.lean.js similarity index 91% rename from assets/garden_kronos_index.md.BX3T3aQP.lean.js rename to assets/garden_kronos_index.md.dlLMxxFW.lean.js index baa9b4101..e85cc469b 100644 --- a/assets/garden_kronos_index.md.BX3T3aQP.lean.js +++ b/assets/garden_kronos_index.md.dlLMxxFW.lean.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as s,Q as e,K as o,u as a,ag as i,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Kronos",-1),p=["innerHTML"],m=i("",7),y=JSON.parse('{"title":"Kronos","description":"","frontmatter":{"public":"true","slug":"kronos","tags":["My Projects","Profectus"],"title":"Kronos","prev":false,"next":false},"headers":[],"relativePath":"garden/kronos/index.md","filePath":"garden/kronos/index.md"}'),c={name:"garden/kronos/index.md"},v=Object.assign(c,{setup(u){const t=n();return(_,h)=>(l(),s("div",null,[d,e("p",null,[o("60 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,p)]),m]))}});export{y as __pageData,v as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as s,Q as e,K as o,u as a,ag as i,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Kronos",-1),p=["innerHTML"],m=i("",7),y=JSON.parse('{"title":"Kronos","description":"","frontmatter":{"public":"true","slug":"kronos","tags":["My Projects","Profectus"],"title":"Kronos","prev":false,"next":false},"headers":[],"relativePath":"garden/kronos/index.md","filePath":"garden/kronos/index.md"}'),c={name:"garden/kronos/index.md"},v=Object.assign(c,{setup(u){const t=n();return(_,h)=>(l(),s("div",null,[d,e("p",null,[o("60 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,p)]),m]))}});export{y as __pageData,v as default}; diff --git a/assets/garden_leftism_index.md.CYOK2kei.js b/assets/garden_leftism_index.md.DU61D021.js similarity index 99% rename from assets/garden_leftism_index.md.CYOK2kei.js rename to assets/garden_leftism_index.md.DU61D021.js index d2765a146..dc78c30ed 100644 --- a/assets/garden_leftism_index.md.CYOK2kei.js +++ b/assets/garden_leftism_index.md.DU61D021.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as s,Q as e,K as r,u as t,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Leftism",-1),c=["innerHTML"],d=n('
Referenced by:DebateFilter BubblesMy Political BeliefsMy Political Journey

My Political Journey has brought me to the broad label of being a leftist. Leftism encompasses many ideologies, each with unique visions for an egalitarian society and strategies to achieve it. These pages are my tool to test my understanding by articulating these ideas in my own terms. I don't care to label myself any further than leftist, as in my mind I'm still a student of leftist ideologies and have personally been finding insight across the spectrum of leftist ideologies. As a reminder, this digital garden is a perpetual work in progress and only reflects my understanding of a topic at time of writing.

What is Leftism?

Leftism refers to a wide range of political ideologies that share a general opposition to hierarchical structures, particularly class hierarchies. Leftists seek an egalitarian society, though their vision of what this entails and how to achieve it vary significantly. They aim to replace systems based on profit and exploitation with ones prioritizing collective well-being. This typically places them against capitalism, however some leftists seek to retain the role of markets and sometimes even private property.

Major Leftist Ideologies

Marxism-Leninism

Marxist-Leninists believe the way towards communism - a classless, stateless, moneyless society - requires a transitionary phase called the "dictatorship of the proletariat". This involves a revolutionary vanguard party seizing control of the state to protect against counter-revolutionary forces and reorganize society along socialist lines. The vanguard party will typically do so by taking advantage of a crisis brought on by the contradictions of capitalism. As material abundance is achieved and exploitation becomes structurally impossible, the state will "wither away," giving rise to communism.

Examples of MLism include the Soviet Union and other 20th century communist movements.

Critiques of MLism focus on the authoritarian nature of the transitionary phase and whether the state will truly willingly "wither away" as described.

Maoism and Dengism are adaptations of MLism that apply it to the specific context of China following its Communist Revolution.

Anarchism

Anarchists reject the state entirely, viewing it as an inherently oppressive institution that cannot be reformed or repurposed for liberation. Anarchism envisions the immediate transition to a classless, stateless, moneyless society organized through voluntary associations, mutual aid, and decentralized decision-making. Unlike Marxist-Leninists, anarchists argue against any transitionary state, believing it will perpetuate hierarchy rather than dismantle it.

Historical examples include the anarchist collectives in Catalonia during the Spanish Civil War, which experimented with decentralized governance and worker control.

Critics of anarchism often point to decentralized systems being harder to "scale up" without introducing oppressive hierarchies, and their vulnerability to coordinated external threats.

The page dedicated to anarchism will philosophically explore what a stateless society looks like, but does not really cover the process of transitioning from capitalism to anarchism, as I have little confidence such a process is truly possible without a state to protect it, so long as capitalists and other reactionary powers exist.

Market Socialisms and Reformism

In contrast to anarchism and communism, these ideologies see markets as a tool for innovation and resource allocation, and argue for transitioning an existing state towards socialism without a vanguard party or revolution.

Syndicalism advocates for decentralized worker control through labor unions that would, through strikes and occupations, control the economy.

Social democracy and democratic socialism focus on reforming capitalist from the existing democratic processes, with the goal of reducing inequality and expanding social welfare. Bernie Sanders is a famous democratic socialist politician in America.

Anarchism vs Communism

Anarchism and communism are interesting in that they both describe a classless, stateless, and moneyless society. A society free from class antagonisms and the coercive apparatus of the state. They're both materialist schools of thought that both aim for the collective liberation of all and the abolition of hierarchical power structures. Yet famously these two groups have been at odds throughout history, such as after the Russian Revolution. They have a fundamental disagreement on how to arrive at their ideal society, and those differences are very interesting to explore. These differences not only feed into conflicts between the two groups, but undoubtedly yet subtly shape the society they're ostensibly both striving for.

Communism Strategy

Communists argue for a transitionary state - the "dictatorship of the proletariat" - as necessary for defending the revolution from both internal and external counter-revolutionary forces, as well as reorganizing the economy along socialist and eventually communism lines. This is a very long process, as they ultimately believe they need to abolish the material basis for class society, perhaps on a global scale due to Imperialism , before the process is complete. Nevertheless, the state is still seen as a temporary mechanism that will eventually become obsolete and naturally "wither away", as described by Lenin in State and Revolution:

And so in capitalist society we have a democracy that is curtailed, wretched, false, a democracy only for the rich, for the minority. The dictatorship of the proletariat, the period of transition to communism, will for the first time create democracy for the people, for the majority, along with the necessary suppression of the exploiters, of the minority. Communism alone is capable of providing really complete democracy, and the more complete it is, the sooner it will become unnecessary and wither away of its own accord.

In the same document, Lenin describes a talk by Engels to anarchists where he exasperatedly points out they share a common vision for ideal society, and they just disagree on the justifications for a transitionary state. Engels believed not installing the transitionary state would mean not being able to "crush the resistance of the bourgeoisie". That the immediate abolition of the state is impractical in the face of the immense power of capitalist and other reactionary forces.

Anarchist Strategy

Anarchists, on the other hand, refute the concept of a transitionary state as a necessary construct; they see installing a state of any kind as a reactionary obstacle to achieving their ideal society. Anarchists see the state as an inherently oppressive institution that cannot be reformed nor repurposed for liberation. As put by Kropotkin in The State: Its Historic Role:

There are those, on the one hand, who hope to achieve the social revolution through the State by preserving and even extending most of its powers to be used for the revolution. And there are those like ourselves who see the State, both in its present form, in its very essence, and in whatever guise it might appear, an obstacle to the social revolution, the greatest hindrance to the birth of a society based on equality and liberty, as well as the historic means designed to prevent this blossoming. The latter work to abolish the State and not to reform it.

They argue that regardless of intent, states are structurally designed to centralize power and perpetuate hierarchy. They believe a state will intrinsically lead to a new ruling class and undermining the revolutionary aims of equality and freedom. And most importantly, they do not accept that a state could "wither away of its own accord", but rather would forever justify its continued existence. As Bakunin put in Statism and Anarchy:

The differences between revolutionary dictatorship and statism are superficial. Fundamentally they both represent the same principle of minority rule over the majority in the name of the alleged “stupidity” of the latter and the alleged “intelligence” of the former. Therefore they are both equally reactionary since both directly and inevitably must preserve and perpetuate the political and economic privileges of the ruling minority and the political and economic subjugation of the masses of the people.

It should be noted that Marx responded to this text, reaffirming that the state would go away due to resource distribution becoming apolitical once abundance is achieved.

Naturally, anarchists also do not believe the economic role of the transitionary state is necessary either, but that a society, even pre-revolution, can work towards meeting the needs of everyone at the local community level through mutual aid and a focus on sustainable living.

Differences in their Visions

Due to the different paths to get there, the society each group strives for will be distinct in important ways, despite sharing the common characteristics of being classless, stateless, and moneyless. Communists arrived here almost incidentally after eradicating the material conditions for exploitation. They'll have reached an economic state of abundance, post-scarcity. Although Lenin makes it clear he still believes individuals can consume in excess and must be stopped, although he does not see the state as necessary for that effort:

We are not utopians, and do not in the least deny the possibility and inevitability of excesses on the part of individual persons, or the need to stop such excesses. In the first place, however, no special machine, no special apparatus of suppression, is needed for this: this will be done by the armed people themselves, as simply and as readily as any crowd of civilized people, even in modern society, interferes to put a stop to a scuffle or to prevent a woman from being assaulted. And, secondly, we know that the fundamental social cause of excesses, which consist in the violation of the rules of social intercourse, is the exploitation of the people, their want and their poverty. With the removal of this chief cause, excesses will inevitably begin to "wither away".

The take away here is that the communist vision may happen to be stateless and even follow some anarchist principles, but it was not designed to rigorously uphold all anarchist values. Of particular note, the advanced productive powers developed by the transitionary state would likely be a fairly centralized construct, even without a formal state, which anarchists would see as a coercive force that goes against the principle of free association. Anarchists, instead, would keep the economy decentralized, managing production on the local level guided by the principles of mutual aid and sustainability.

Leftist Infighting

Leftist infighting has long been a meme. While their disagreements are inevitable and valid, their intensity is often exacerbated by external forces seeking to dismantle leftist movements. The lack of a unifying framework is what makes leftism in particular susceptible to infighting.

The status quo creates an aligning force for similar ideologies, and makes any ideologies far away from the status quo feel comparatively dissimilar.

Marxist-Leninists advocate for a concept called democratic centralism to combat infighting. It mandates unity of action while allowing for internal debate and discussion. It's particularly useful and relevant for a vanguard party to ensure it is clear who has taken power following a revolution, rather than creating a power vacuum that can be exploited by imperialist powers. However, critics argue democratic centralism can stifle dissent and foster authoritarianism.

Moving Forward

As I describe in A Plea to Organize, despite differences between the different ideologies, my advice is still the same: Organize! Join local communities, regardless of affiliation, and support leftism and the community. Mutual aid efforts are particularly helpful and can be found on Mutual Aid Hub.

Additionally: Study! Read theory and better understand leftist ideologies of all stripes. It helps you better understand the philosophies underpinning these ideologies and in turn become a better leftist.

',44),b=JSON.parse('{"title":"Leftism","description":"","frontmatter":{"alias":"Leftist","public":"true","slug":"leftism","title":"Leftism","prev":false,"next":false},"headers":[],"relativePath":"garden/leftism/index.md","filePath":"garden/leftism/index.md"}'),m={name:"garden/leftism/index.md"},v=Object.assign(m,{setup(u){const a=o();return(p,f)=>(l(),s("div",null,[h,e("p",null,[r("1794 words, ~10 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),d]))}});export{b as __pageData,v as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as s,Q as e,K as r,u as t,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Leftism",-1),c=["innerHTML"],d=n('
Referenced by:DebateFilter BubblesMy Political BeliefsMy Political Journey

My Political Journey has brought me to the broad label of being a leftist. Leftism encompasses many ideologies, each with unique visions for an egalitarian society and strategies to achieve it. These pages are my tool to test my understanding by articulating these ideas in my own terms. I don't care to label myself any further than leftist, as in my mind I'm still a student of leftist ideologies and have personally been finding insight across the spectrum of leftist ideologies. As a reminder, this digital garden is a perpetual work in progress and only reflects my understanding of a topic at time of writing.

What is Leftism?

Leftism refers to a wide range of political ideologies that share a general opposition to hierarchical structures, particularly class hierarchies. Leftists seek an egalitarian society, though their vision of what this entails and how to achieve it vary significantly. They aim to replace systems based on profit and exploitation with ones prioritizing collective well-being. This typically places them against capitalism, however some leftists seek to retain the role of markets and sometimes even private property.

Major Leftist Ideologies

Marxism-Leninism

Marxist-Leninists believe the way towards communism - a classless, stateless, moneyless society - requires a transitionary phase called the "dictatorship of the proletariat". This involves a revolutionary vanguard party seizing control of the state to protect against counter-revolutionary forces and reorganize society along socialist lines. The vanguard party will typically do so by taking advantage of a crisis brought on by the contradictions of capitalism. As material abundance is achieved and exploitation becomes structurally impossible, the state will "wither away," giving rise to communism.

Examples of MLism include the Soviet Union and other 20th century communist movements.

Critiques of MLism focus on the authoritarian nature of the transitionary phase and whether the state will truly willingly "wither away" as described.

Maoism and Dengism are adaptations of MLism that apply it to the specific context of China following its Communist Revolution.

Anarchism

Anarchists reject the state entirely, viewing it as an inherently oppressive institution that cannot be reformed or repurposed for liberation. Anarchism envisions the immediate transition to a classless, stateless, moneyless society organized through voluntary associations, mutual aid, and decentralized decision-making. Unlike Marxist-Leninists, anarchists argue against any transitionary state, believing it will perpetuate hierarchy rather than dismantle it.

Historical examples include the anarchist collectives in Catalonia during the Spanish Civil War, which experimented with decentralized governance and worker control.

Critics of anarchism often point to decentralized systems being harder to "scale up" without introducing oppressive hierarchies, and their vulnerability to coordinated external threats.

The page dedicated to anarchism will philosophically explore what a stateless society looks like, but does not really cover the process of transitioning from capitalism to anarchism, as I have little confidence such a process is truly possible without a state to protect it, so long as capitalists and other reactionary powers exist.

Market Socialisms and Reformism

In contrast to anarchism and communism, these ideologies see markets as a tool for innovation and resource allocation, and argue for transitioning an existing state towards socialism without a vanguard party or revolution.

Syndicalism advocates for decentralized worker control through labor unions that would, through strikes and occupations, control the economy.

Social democracy and democratic socialism focus on reforming capitalist from the existing democratic processes, with the goal of reducing inequality and expanding social welfare. Bernie Sanders is a famous democratic socialist politician in America.

Anarchism vs Communism

Anarchism and communism are interesting in that they both describe a classless, stateless, and moneyless society. A society free from class antagonisms and the coercive apparatus of the state. They're both materialist schools of thought that both aim for the collective liberation of all and the abolition of hierarchical power structures. Yet famously these two groups have been at odds throughout history, such as after the Russian Revolution. They have a fundamental disagreement on how to arrive at their ideal society, and those differences are very interesting to explore. These differences not only feed into conflicts between the two groups, but undoubtedly yet subtly shape the society they're ostensibly both striving for.

Communism Strategy

Communists argue for a transitionary state - the "dictatorship of the proletariat" - as necessary for defending the revolution from both internal and external counter-revolutionary forces, as well as reorganizing the economy along socialist and eventually communism lines. This is a very long process, as they ultimately believe they need to abolish the material basis for class society, perhaps on a global scale due to Imperialism , before the process is complete. Nevertheless, the state is still seen as a temporary mechanism that will eventually become obsolete and naturally "wither away", as described by Lenin in State and Revolution:

And so in capitalist society we have a democracy that is curtailed, wretched, false, a democracy only for the rich, for the minority. The dictatorship of the proletariat, the period of transition to communism, will for the first time create democracy for the people, for the majority, along with the necessary suppression of the exploiters, of the minority. Communism alone is capable of providing really complete democracy, and the more complete it is, the sooner it will become unnecessary and wither away of its own accord.

In the same document, Lenin describes a talk by Engels to anarchists where he exasperatedly points out they share a common vision for ideal society, and they just disagree on the justifications for a transitionary state. Engels believed not installing the transitionary state would mean not being able to "crush the resistance of the bourgeoisie". That the immediate abolition of the state is impractical in the face of the immense power of capitalist and other reactionary forces.

Anarchist Strategy

Anarchists, on the other hand, refute the concept of a transitionary state as a necessary construct; they see installing a state of any kind as a reactionary obstacle to achieving their ideal society. Anarchists see the state as an inherently oppressive institution that cannot be reformed nor repurposed for liberation. As put by Kropotkin in The State: Its Historic Role:

There are those, on the one hand, who hope to achieve the social revolution through the State by preserving and even extending most of its powers to be used for the revolution. And there are those like ourselves who see the State, both in its present form, in its very essence, and in whatever guise it might appear, an obstacle to the social revolution, the greatest hindrance to the birth of a society based on equality and liberty, as well as the historic means designed to prevent this blossoming. The latter work to abolish the State and not to reform it.

They argue that regardless of intent, states are structurally designed to centralize power and perpetuate hierarchy. They believe a state will intrinsically lead to a new ruling class and undermining the revolutionary aims of equality and freedom. And most importantly, they do not accept that a state could "wither away of its own accord", but rather would forever justify its continued existence. As Bakunin put in Statism and Anarchy:

The differences between revolutionary dictatorship and statism are superficial. Fundamentally they both represent the same principle of minority rule over the majority in the name of the alleged “stupidity” of the latter and the alleged “intelligence” of the former. Therefore they are both equally reactionary since both directly and inevitably must preserve and perpetuate the political and economic privileges of the ruling minority and the political and economic subjugation of the masses of the people.

It should be noted that Marx responded to this text, reaffirming that the state would go away due to resource distribution becoming apolitical once abundance is achieved.

Naturally, anarchists also do not believe the economic role of the transitionary state is necessary either, but that a society, even pre-revolution, can work towards meeting the needs of everyone at the local community level through mutual aid and a focus on sustainable living.

Differences in their Visions

Due to the different paths to get there, the society each group strives for will be distinct in important ways, despite sharing the common characteristics of being classless, stateless, and moneyless. Communists arrived here almost incidentally after eradicating the material conditions for exploitation. They'll have reached an economic state of abundance, post-scarcity. Although Lenin makes it clear he still believes individuals can consume in excess and must be stopped, although he does not see the state as necessary for that effort:

We are not utopians, and do not in the least deny the possibility and inevitability of excesses on the part of individual persons, or the need to stop such excesses. In the first place, however, no special machine, no special apparatus of suppression, is needed for this: this will be done by the armed people themselves, as simply and as readily as any crowd of civilized people, even in modern society, interferes to put a stop to a scuffle or to prevent a woman from being assaulted. And, secondly, we know that the fundamental social cause of excesses, which consist in the violation of the rules of social intercourse, is the exploitation of the people, their want and their poverty. With the removal of this chief cause, excesses will inevitably begin to "wither away".

The take away here is that the communist vision may happen to be stateless and even follow some anarchist principles, but it was not designed to rigorously uphold all anarchist values. Of particular note, the advanced productive powers developed by the transitionary state would likely be a fairly centralized construct, even without a formal state, which anarchists would see as a coercive force that goes against the principle of free association. Anarchists, instead, would keep the economy decentralized, managing production on the local level guided by the principles of mutual aid and sustainability.

Leftist Infighting

Leftist infighting has long been a meme. While their disagreements are inevitable and valid, their intensity is often exacerbated by external forces seeking to dismantle leftist movements. The lack of a unifying framework is what makes leftism in particular susceptible to infighting.

The status quo creates an aligning force for similar ideologies, and makes any ideologies far away from the status quo feel comparatively dissimilar.

Marxist-Leninists advocate for a concept called democratic centralism to combat infighting. It mandates unity of action while allowing for internal debate and discussion. It's particularly useful and relevant for a vanguard party to ensure it is clear who has taken power following a revolution, rather than creating a power vacuum that can be exploited by imperialist powers. However, critics argue democratic centralism can stifle dissent and foster authoritarianism.

Moving Forward

As I describe in A Plea to Organize, despite differences between the different ideologies, my advice is still the same: Organize! Join local communities, regardless of affiliation, and support leftism and the community. Mutual aid efforts are particularly helpful and can be found on Mutual Aid Hub.

Additionally: Study! Read theory and better understand leftist ideologies of all stripes. It helps you better understand the philosophies underpinning these ideologies and in turn become a better leftist.

',44),b=JSON.parse('{"title":"Leftism","description":"","frontmatter":{"alias":"Leftist","public":"true","slug":"leftism","title":"Leftism","prev":false,"next":false},"headers":[],"relativePath":"garden/leftism/index.md","filePath":"garden/leftism/index.md"}'),m={name:"garden/leftism/index.md"},v=Object.assign(m,{setup(u){const a=o();return(p,f)=>(l(),s("div",null,[h,e("p",null,[r("1794 words, ~10 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),d]))}});export{b as __pageData,v as default}; diff --git a/assets/garden_leftism_index.md.CYOK2kei.lean.js b/assets/garden_leftism_index.md.DU61D021.lean.js similarity index 91% rename from assets/garden_leftism_index.md.CYOK2kei.lean.js rename to assets/garden_leftism_index.md.DU61D021.lean.js index dbafe0b11..79ffe6682 100644 --- a/assets/garden_leftism_index.md.CYOK2kei.lean.js +++ b/assets/garden_leftism_index.md.DU61D021.lean.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as s,Q as e,K as r,u as t,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Leftism",-1),c=["innerHTML"],d=n("",44),b=JSON.parse('{"title":"Leftism","description":"","frontmatter":{"alias":"Leftist","public":"true","slug":"leftism","title":"Leftism","prev":false,"next":false},"headers":[],"relativePath":"garden/leftism/index.md","filePath":"garden/leftism/index.md"}'),m={name:"garden/leftism/index.md"},v=Object.assign(m,{setup(u){const a=o();return(p,f)=>(l(),s("div",null,[h,e("p",null,[r("1794 words, ~10 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),d]))}});export{b as __pageData,v as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as s,Q as e,K as r,u as t,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Leftism",-1),c=["innerHTML"],d=n("",44),b=JSON.parse('{"title":"Leftism","description":"","frontmatter":{"alias":"Leftist","public":"true","slug":"leftism","title":"Leftism","prev":false,"next":false},"headers":[],"relativePath":"garden/leftism/index.md","filePath":"garden/leftism/index.md"}'),m={name:"garden/leftism/index.md"},v=Object.assign(m,{setup(u){const a=o();return(p,f)=>(l(),s("div",null,[h,e("p",null,[r("1794 words, ~10 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),d]))}});export{b as __pageData,v as default}; diff --git a/assets/garden_life-is-strange_index.md.CQykqggC.js b/assets/garden_life-is-strange_index.md.CiHEZNoV.js similarity index 99% rename from assets/garden_life-is-strange_index.md.CQykqggC.js rename to assets/garden_life-is-strange_index.md.CiHEZNoV.js index b59acee87..119d521ce 100644 --- a/assets/garden_life-is-strange_index.md.CQykqggC.js +++ b/assets/garden_life-is-strange_index.md.CiHEZNoV.js @@ -1 +1 @@ -import{M as i,q as r,Q as e,K as s,u as t,ag as o,p as n,at as l,au as h}from"./chunks/framework.Sr2_9k8k.js";import{d}from"./chunks/git.data.D-Ga3RhB.js";const g=e("h1",{class:"p-name"},"Life is Strange",-1),c=["innerHTML"],m=o('

A series of narrative driven video games with a focus on player choices

I really enjoyed the first game and engaged with the community a lot. I would get very emotional playing through the later chapters, and it became one of my favorite games.

Playthroughs I enjoyed:

Around the start of Haley and I's relationship, we'd play through LiS1 on projectors in our's classrooms

The ending

I was not a huge fan of the ending of Life is Strange. Of the two endings, one very clearly got a lot more resources spent on it, but I think Max's story has a better conclusion under the other.

In my mind, Max's arc (and major themes of the last chapter) was about learning not to rely on her powers, and to learn to live with the consequences of her actions. To that end, having the game end with her taking responsibility and living with the consequences of such a major event is a fitting thematic conclusion to the game and her character arc. In contrast, the other ending shows Max relying on her powers once again and, in my opinion, portrays Max as having not grown nor learned any lessons throughout the entire series. I think its a disservice this ending got so much more attention, with unique outfits and a song dedicated to it.

Life is Strange: Before the Storm

I really enjoyed this story. I didn't get quite as invested, perhaps due to it being a condensed 3 chapters rather than 5, but the characters will still just as amazing, which is what makes LiS so good. The ending didn't have as much of a punch as LiS1 - in fact, the entire back half of episode 3 didn't quite meet the bar in my eyes. At the time, I enjoyed these threads discussing criticisms levied at that part of the game:

Deadbones played through the game here

The Awesome Adventures of Captain Spirit

I enjoyed the demo, and it certainly got me hyped for LiS2 (although I would've been regardless). Switching to UE seemed like a really good move, and the comic theme fits the aesthetic of the series well.

Life is Strange 2

Unfortunately, I've only played the first chapter of this game. I wanted to play through it with Haley, but we haven't found time to do so.

LATER Skip the rest of LiS1 and play LiS2 with Haley

Life is Strange: True Colors

This game seems interesting, although the power does seem a little funnily close to "has empathy". I haven't had time to play it, but would like to.

Life is Strange: Double Exposure

I'm very excited for this game! Returning to Max's story sounds awesome. Although I will say, from the trailer alone it's incredibly obvious what one of the story beats will be: Revealing that the two timelines follow the two disparate endings from LiS1.

This game was announced to come with premium editions that get access to the game earlier

  • I think this is a horrible anti-consumer practice
  • Since this game is narratively driven, it is prone to spoilers
  • They're getting more money from their biggest fans without providing any tangible value to them, other than making the experience worse for everyone who plays but doesn't cough up that money
  • I hope other narratively driven games find other ways to do Video Game Monetization
',25),b=JSON.parse('{"title":"Life is Strange","description":"","frontmatter":{"public":"true","slug":"life-is-strange","title":"Life is Strange","prev":false,"next":false},"headers":[],"relativePath":"garden/life-is-strange/index.md","filePath":"garden/life-is-strange/index.md"}'),u={name:"garden/life-is-strange/index.md"},v=Object.assign(u,{setup(f){const a=i();return(p,w)=>(n(),r("div",null,[g,e("p",null,[s("654 words, ~4 minute read. "),e("span",{innerHTML:t(d)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),m]))}});export{b as __pageData,v as default}; +import{M as i,q as r,Q as e,K as s,u as t,ag as o,p as n,at as l,au as h}from"./chunks/framework.Sr2_9k8k.js";import{d}from"./chunks/git.data.BcrWSzMU.js";const g=e("h1",{class:"p-name"},"Life is Strange",-1),c=["innerHTML"],m=o('

A series of narrative driven video games with a focus on player choices

I really enjoyed the first game and engaged with the community a lot. I would get very emotional playing through the later chapters, and it became one of my favorite games.

Playthroughs I enjoyed:

Around the start of Haley and I's relationship, we'd play through LiS1 on projectors in our's classrooms

The ending

I was not a huge fan of the ending of Life is Strange. Of the two endings, one very clearly got a lot more resources spent on it, but I think Max's story has a better conclusion under the other.

In my mind, Max's arc (and major themes of the last chapter) was about learning not to rely on her powers, and to learn to live with the consequences of her actions. To that end, having the game end with her taking responsibility and living with the consequences of such a major event is a fitting thematic conclusion to the game and her character arc. In contrast, the other ending shows Max relying on her powers once again and, in my opinion, portrays Max as having not grown nor learned any lessons throughout the entire series. I think its a disservice this ending got so much more attention, with unique outfits and a song dedicated to it.

Life is Strange: Before the Storm

I really enjoyed this story. I didn't get quite as invested, perhaps due to it being a condensed 3 chapters rather than 5, but the characters will still just as amazing, which is what makes LiS so good. The ending didn't have as much of a punch as LiS1 - in fact, the entire back half of episode 3 didn't quite meet the bar in my eyes. At the time, I enjoyed these threads discussing criticisms levied at that part of the game:

Deadbones played through the game here

The Awesome Adventures of Captain Spirit

I enjoyed the demo, and it certainly got me hyped for LiS2 (although I would've been regardless). Switching to UE seemed like a really good move, and the comic theme fits the aesthetic of the series well.

Life is Strange 2

Unfortunately, I've only played the first chapter of this game. I wanted to play through it with Haley, but we haven't found time to do so.

LATER Skip the rest of LiS1 and play LiS2 with Haley

Life is Strange: True Colors

This game seems interesting, although the power does seem a little funnily close to "has empathy". I haven't had time to play it, but would like to.

Life is Strange: Double Exposure

I'm very excited for this game! Returning to Max's story sounds awesome. Although I will say, from the trailer alone it's incredibly obvious what one of the story beats will be: Revealing that the two timelines follow the two disparate endings from LiS1.

This game was announced to come with premium editions that get access to the game earlier

  • I think this is a horrible anti-consumer practice
  • Since this game is narratively driven, it is prone to spoilers
  • They're getting more money from their biggest fans without providing any tangible value to them, other than making the experience worse for everyone who plays but doesn't cough up that money
  • I hope other narratively driven games find other ways to do Video Game Monetization
',25),b=JSON.parse('{"title":"Life is Strange","description":"","frontmatter":{"public":"true","slug":"life-is-strange","title":"Life is Strange","prev":false,"next":false},"headers":[],"relativePath":"garden/life-is-strange/index.md","filePath":"garden/life-is-strange/index.md"}'),u={name:"garden/life-is-strange/index.md"},v=Object.assign(u,{setup(f){const a=i();return(p,w)=>(n(),r("div",null,[g,e("p",null,[s("654 words, ~4 minute read. "),e("span",{innerHTML:t(d)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),m]))}});export{b as __pageData,v as default}; diff --git a/assets/garden_life-is-strange_index.md.CQykqggC.lean.js b/assets/garden_life-is-strange_index.md.CiHEZNoV.lean.js similarity index 91% rename from assets/garden_life-is-strange_index.md.CQykqggC.lean.js rename to assets/garden_life-is-strange_index.md.CiHEZNoV.lean.js index b63c5f035..5d37aaf12 100644 --- a/assets/garden_life-is-strange_index.md.CQykqggC.lean.js +++ b/assets/garden_life-is-strange_index.md.CiHEZNoV.lean.js @@ -1 +1 @@ -import{M as i,q as r,Q as e,K as s,u as t,ag as o,p as n,at as l,au as h}from"./chunks/framework.Sr2_9k8k.js";import{d}from"./chunks/git.data.D-Ga3RhB.js";const g=e("h1",{class:"p-name"},"Life is Strange",-1),c=["innerHTML"],m=o("",25),b=JSON.parse('{"title":"Life is Strange","description":"","frontmatter":{"public":"true","slug":"life-is-strange","title":"Life is Strange","prev":false,"next":false},"headers":[],"relativePath":"garden/life-is-strange/index.md","filePath":"garden/life-is-strange/index.md"}'),u={name:"garden/life-is-strange/index.md"},v=Object.assign(u,{setup(f){const a=i();return(p,w)=>(n(),r("div",null,[g,e("p",null,[s("654 words, ~4 minute read. "),e("span",{innerHTML:t(d)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),m]))}});export{b as __pageData,v as default}; +import{M as i,q as r,Q as e,K as s,u as t,ag as o,p as n,at as l,au as h}from"./chunks/framework.Sr2_9k8k.js";import{d}from"./chunks/git.data.BcrWSzMU.js";const g=e("h1",{class:"p-name"},"Life is Strange",-1),c=["innerHTML"],m=o("",25),b=JSON.parse('{"title":"Life is Strange","description":"","frontmatter":{"public":"true","slug":"life-is-strange","title":"Life is Strange","prev":false,"next":false},"headers":[],"relativePath":"garden/life-is-strange/index.md","filePath":"garden/life-is-strange/index.md"}'),u={name:"garden/life-is-strange/index.md"},v=Object.assign(u,{setup(f){const a=i();return(p,w)=>(n(),r("div",null,[g,e("p",null,[s("654 words, ~4 minute read. "),e("span",{innerHTML:t(d)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),m]))}});export{b as __pageData,v as default}; diff --git a/assets/garden_local-communities_index.md.D3DH0fGC.js b/assets/garden_local-communities_index.md.CAEN6S2r.js similarity index 98% rename from assets/garden_local-communities_index.md.D3DH0fGC.js rename to assets/garden_local-communities_index.md.CAEN6S2r.js index c6137925c..e358b3444 100644 --- a/assets/garden_local-communities_index.md.D3DH0fGC.js +++ b/assets/garden_local-communities_index.md.CAEN6S2r.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as o,Q as e,K as s,u as t,ag as r,p as c}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Local Communities",-1),d=["innerHTML"],m=r('
Referenced by:AnarchismDigital LocalityIndividualism

Strongly connected local communities are important to have. They satisfy our social needs for in-person connections, and help organize mutual aid. These needs cannot be sufficiently satisfied exclusively by online friends/communities - of particular note, new parents need help raising their kid.

Historically, society has had these strongly connected local communities, via the way society was organized (i.e. tribes, multi-generational households, etc.) or through entities that focused on community (i.e. local churches). Churches in particular would ensure everyone meets up regularly to see each other, connect, and catch up. They'd host community events and services throughout the year, and mobilize the community during emergencies.

The religious aspect of churches was never a requirement for the benefits they contributed to their local communities, and in fact there are mega-churches today that do not confer these benefits despite retaining the religious aspect.

There are several reasons for why local communities have since weakened. The car has weakened them by making the people physically more spread out and reducing the number of "third places". The internet created a convenient alternative whose communities were not immediately recognized as insufficient imitations of in person communities. Newer generations trend towards irreligiousness, making churches decreasingly popular. Combined, these changes have led to a cultural shift towards Individualism and Neoliberalism that has further cemented our weakened local communities.

The way to "fix" our local communities and make them more strongly connected is to support multi-generational households, increasing population density, and using or creating entities that can replace the community-building role of the church. Such alternatives could be community centers or HOAs. HOAs get a bad reputation due to their tendency to attract those who want power to micro-manage the community, but there are ways to organize them to mitigate that issue (see Anarchism).

',7),_=JSON.parse('{"title":"Local Communities","description":"","frontmatter":{"public":"true","slug":"local-communities","title":"Local Communities","prev":false,"next":false},"headers":[],"relativePath":"garden/local-communities/index.md","filePath":"garden/local-communities/index.md"}'),u={name:"garden/local-communities/index.md"},v=Object.assign(u,{setup(h){const a=n();return(p,g)=>(c(),o("div",null,[l,e("p",null,[s("302 words, ~2 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),m]))}});export{_ as __pageData,v as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as o,Q as e,K as s,u as t,ag as r,p as c}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Local Communities",-1),d=["innerHTML"],m=r('
Referenced by:AnarchismDigital LocalityIndividualism

Strongly connected local communities are important to have. They satisfy our social needs for in-person connections, and help organize mutual aid. These needs cannot be sufficiently satisfied exclusively by online friends/communities - of particular note, new parents need help raising their kid.

Historically, society has had these strongly connected local communities, via the way society was organized (i.e. tribes, multi-generational households, etc.) or through entities that focused on community (i.e. local churches). Churches in particular would ensure everyone meets up regularly to see each other, connect, and catch up. They'd host community events and services throughout the year, and mobilize the community during emergencies.

The religious aspect of churches was never a requirement for the benefits they contributed to their local communities, and in fact there are mega-churches today that do not confer these benefits despite retaining the religious aspect.

There are several reasons for why local communities have since weakened. The car has weakened them by making the people physically more spread out and reducing the number of "third places". The internet created a convenient alternative whose communities were not immediately recognized as insufficient imitations of in person communities. Newer generations trend towards irreligiousness, making churches decreasingly popular. Combined, these changes have led to a cultural shift towards Individualism and Neoliberalism that has further cemented our weakened local communities.

The way to "fix" our local communities and make them more strongly connected is to support multi-generational households, increasing population density, and using or creating entities that can replace the community-building role of the church. Such alternatives could be community centers or HOAs. HOAs get a bad reputation due to their tendency to attract those who want power to micro-manage the community, but there are ways to organize them to mitigate that issue (see Anarchism).

',7),_=JSON.parse('{"title":"Local Communities","description":"","frontmatter":{"public":"true","slug":"local-communities","title":"Local Communities","prev":false,"next":false},"headers":[],"relativePath":"garden/local-communities/index.md","filePath":"garden/local-communities/index.md"}'),u={name:"garden/local-communities/index.md"},v=Object.assign(u,{setup(h){const a=n();return(p,g)=>(c(),o("div",null,[l,e("p",null,[s("302 words, ~2 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),m]))}});export{_ as __pageData,v as default}; diff --git a/assets/garden_local-communities_index.md.D3DH0fGC.lean.js b/assets/garden_local-communities_index.md.CAEN6S2r.lean.js similarity index 92% rename from assets/garden_local-communities_index.md.D3DH0fGC.lean.js rename to assets/garden_local-communities_index.md.CAEN6S2r.lean.js index ceb210871..bbeb3f58d 100644 --- a/assets/garden_local-communities_index.md.D3DH0fGC.lean.js +++ b/assets/garden_local-communities_index.md.CAEN6S2r.lean.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as o,Q as e,K as s,u as t,ag as r,p as c}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Local Communities",-1),d=["innerHTML"],m=r("",7),_=JSON.parse('{"title":"Local Communities","description":"","frontmatter":{"public":"true","slug":"local-communities","title":"Local Communities","prev":false,"next":false},"headers":[],"relativePath":"garden/local-communities/index.md","filePath":"garden/local-communities/index.md"}'),u={name:"garden/local-communities/index.md"},v=Object.assign(u,{setup(h){const a=n();return(p,g)=>(c(),o("div",null,[l,e("p",null,[s("302 words, ~2 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),m]))}});export{_ as __pageData,v as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as o,Q as e,K as s,u as t,ag as r,p as c}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Local Communities",-1),d=["innerHTML"],m=r("",7),_=JSON.parse('{"title":"Local Communities","description":"","frontmatter":{"public":"true","slug":"local-communities","title":"Local Communities","prev":false,"next":false},"headers":[],"relativePath":"garden/local-communities/index.md","filePath":"garden/local-communities/index.md"}'),u={name:"garden/local-communities/index.md"},v=Object.assign(u,{setup(h){const a=n();return(p,g)=>(c(),o("div",null,[l,e("p",null,[s("302 words, ~2 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),m]))}});export{_ as __pageData,v as default}; diff --git a/assets/garden_local-first-software_index.md.D2a4gu-W.js b/assets/garden_local-first-software_index.md.Cb7v9klo.js similarity index 95% rename from assets/garden_local-first-software_index.md.D2a4gu-W.js rename to assets/garden_local-first-software_index.md.Cb7v9klo.js index 84a4e1934..b039e68b8 100644 --- a/assets/garden_local-first-software_index.md.D2a4gu-W.js +++ b/assets/garden_local-first-software_index.md.Cb7v9klo.js @@ -1 +1 @@ -import{d as s}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as o,Q as e,K as a,u as t,p as l}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"Local-First Software",-1),c=["innerHTML"],d=e("hr",null,null,-1),f=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/orchard/index.md"},"Orchard")],-1),h=e("p",null,"Software that is designed to operate fully offline, that can sync when connected to other clients. This means giving users ownership over their data while still allowing for collaboration.",-1),p=e("p",null,[a("Find a bunch of resources explaining the concept, how to implement it, and some examples at "),e("a",{href:"https://localfirstweb.dev/",target:"_blank",rel:"noreferrer"},"https://localfirstweb.dev/")],-1),v=JSON.parse('{"title":"Local-First Software","description":"","frontmatter":{"public":"true","slug":"local-first-software","title":"Local-First Software","prev":false,"next":false},"headers":[],"relativePath":"garden/local-first-software/index.md","filePath":"garden/local-first-software/index.md"}'),u={name:"garden/local-first-software/index.md"},b=Object.assign(u,{setup(_){const r=n();return(m,w)=>(l(),o("div",null,[i,e("p",null,[a("48 words, ~0 minute read. "),e("span",{innerHTML:t(s)[`site/${t(r).page.value.relativePath}`]},null,8,c)]),d,f,h,p]))}});export{v as __pageData,b as default}; +import{d as s}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as o,Q as e,K as a,u as t,p as l}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"Local-First Software",-1),c=["innerHTML"],d=e("hr",null,null,-1),f=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/orchard/index.md"},"Orchard")],-1),h=e("p",null,"Software that is designed to operate fully offline, that can sync when connected to other clients. This means giving users ownership over their data while still allowing for collaboration.",-1),p=e("p",null,[a("Find a bunch of resources explaining the concept, how to implement it, and some examples at "),e("a",{href:"https://localfirstweb.dev/",target:"_blank",rel:"noreferrer"},"https://localfirstweb.dev/")],-1),v=JSON.parse('{"title":"Local-First Software","description":"","frontmatter":{"public":"true","slug":"local-first-software","title":"Local-First Software","prev":false,"next":false},"headers":[],"relativePath":"garden/local-first-software/index.md","filePath":"garden/local-first-software/index.md"}'),u={name:"garden/local-first-software/index.md"},b=Object.assign(u,{setup(_){const r=n();return(m,w)=>(l(),o("div",null,[i,e("p",null,[a("48 words, ~0 minute read. "),e("span",{innerHTML:t(s)[`site/${t(r).page.value.relativePath}`]},null,8,c)]),d,f,h,p]))}});export{v as __pageData,b as default}; diff --git a/assets/garden_local-first-software_index.md.D2a4gu-W.lean.js b/assets/garden_local-first-software_index.md.Cb7v9klo.lean.js similarity index 95% rename from assets/garden_local-first-software_index.md.D2a4gu-W.lean.js rename to assets/garden_local-first-software_index.md.Cb7v9klo.lean.js index 84a4e1934..b039e68b8 100644 --- a/assets/garden_local-first-software_index.md.D2a4gu-W.lean.js +++ b/assets/garden_local-first-software_index.md.Cb7v9klo.lean.js @@ -1 +1 @@ -import{d as s}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as o,Q as e,K as a,u as t,p as l}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"Local-First Software",-1),c=["innerHTML"],d=e("hr",null,null,-1),f=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/orchard/index.md"},"Orchard")],-1),h=e("p",null,"Software that is designed to operate fully offline, that can sync when connected to other clients. This means giving users ownership over their data while still allowing for collaboration.",-1),p=e("p",null,[a("Find a bunch of resources explaining the concept, how to implement it, and some examples at "),e("a",{href:"https://localfirstweb.dev/",target:"_blank",rel:"noreferrer"},"https://localfirstweb.dev/")],-1),v=JSON.parse('{"title":"Local-First Software","description":"","frontmatter":{"public":"true","slug":"local-first-software","title":"Local-First Software","prev":false,"next":false},"headers":[],"relativePath":"garden/local-first-software/index.md","filePath":"garden/local-first-software/index.md"}'),u={name:"garden/local-first-software/index.md"},b=Object.assign(u,{setup(_){const r=n();return(m,w)=>(l(),o("div",null,[i,e("p",null,[a("48 words, ~0 minute read. "),e("span",{innerHTML:t(s)[`site/${t(r).page.value.relativePath}`]},null,8,c)]),d,f,h,p]))}});export{v as __pageData,b as default}; +import{d as s}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as o,Q as e,K as a,u as t,p as l}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"Local-First Software",-1),c=["innerHTML"],d=e("hr",null,null,-1),f=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/orchard/index.md"},"Orchard")],-1),h=e("p",null,"Software that is designed to operate fully offline, that can sync when connected to other clients. This means giving users ownership over their data while still allowing for collaboration.",-1),p=e("p",null,[a("Find a bunch of resources explaining the concept, how to implement it, and some examples at "),e("a",{href:"https://localfirstweb.dev/",target:"_blank",rel:"noreferrer"},"https://localfirstweb.dev/")],-1),v=JSON.parse('{"title":"Local-First Software","description":"","frontmatter":{"public":"true","slug":"local-first-software","title":"Local-First Software","prev":false,"next":false},"headers":[],"relativePath":"garden/local-first-software/index.md","filePath":"garden/local-first-software/index.md"}'),u={name:"garden/local-first-software/index.md"},b=Object.assign(u,{setup(_){const r=n();return(m,w)=>(l(),o("div",null,[i,e("p",null,[a("48 words, ~0 minute read. "),e("span",{innerHTML:t(s)[`site/${t(r).page.value.relativePath}`]},null,8,c)]),d,f,h,p]))}});export{v as __pageData,b as default}; diff --git a/assets/garden_logseq_index.md.DO7LVfYN.js b/assets/garden_logseq_index.md.BjYPX9U_.js similarity index 94% rename from assets/garden_logseq_index.md.DO7LVfYN.js rename to assets/garden_logseq_index.md.BjYPX9U_.js index 269c6148b..e5d863b4e 100644 --- a/assets/garden_logseq_index.md.DO7LVfYN.js +++ b/assets/garden_logseq_index.md.BjYPX9U_.js @@ -1 +1 @@ -import{d as s}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as r,Q as e,K as o,u as a,ag as d,p as l}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"Logseq",-1),_=["innerHTML"],c=d('
Referenced by:Command PalettesMy Personal WebsiteThis Knowledge Hub

Logseq is an Open Source outlining software

',3),q=JSON.parse('{"title":"Logseq","description":"","frontmatter":{"public":"true","slug":"logseq","title":"Logseq","prev":false,"next":false},"headers":[],"relativePath":"garden/logseq/index.md","filePath":"garden/logseq/index.md"}'),g={name:"garden/logseq/index.md"},x=Object.assign(g,{setup(m){const t=n();return(p,u)=>(l(),r("div",null,[i,e("p",null,[o("3 words, ~0 minute read. "),e("span",{innerHTML:a(s)[`site/${a(t).page.value.relativePath}`]},null,8,_)]),c]))}});export{q as __pageData,x as default}; +import{d as s}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as r,Q as e,K as o,u as a,ag as d,p as l}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"Logseq",-1),_=["innerHTML"],c=d('
Referenced by:Command PalettesMy Personal WebsiteThis Knowledge Hub

Logseq is an Open Source outlining software

',3),q=JSON.parse('{"title":"Logseq","description":"","frontmatter":{"public":"true","slug":"logseq","title":"Logseq","prev":false,"next":false},"headers":[],"relativePath":"garden/logseq/index.md","filePath":"garden/logseq/index.md"}'),g={name:"garden/logseq/index.md"},x=Object.assign(g,{setup(m){const t=n();return(p,u)=>(l(),r("div",null,[i,e("p",null,[o("3 words, ~0 minute read. "),e("span",{innerHTML:a(s)[`site/${a(t).page.value.relativePath}`]},null,8,_)]),c]))}});export{q as __pageData,x as default}; diff --git a/assets/garden_logseq_index.md.DO7LVfYN.lean.js b/assets/garden_logseq_index.md.BjYPX9U_.lean.js similarity index 91% rename from assets/garden_logseq_index.md.DO7LVfYN.lean.js rename to assets/garden_logseq_index.md.BjYPX9U_.lean.js index b27bc23a3..cf1a58966 100644 --- a/assets/garden_logseq_index.md.DO7LVfYN.lean.js +++ b/assets/garden_logseq_index.md.BjYPX9U_.lean.js @@ -1 +1 @@ -import{d as s}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as r,Q as e,K as o,u as a,ag as d,p as l}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"Logseq",-1),_=["innerHTML"],c=d("",3),q=JSON.parse('{"title":"Logseq","description":"","frontmatter":{"public":"true","slug":"logseq","title":"Logseq","prev":false,"next":false},"headers":[],"relativePath":"garden/logseq/index.md","filePath":"garden/logseq/index.md"}'),g={name:"garden/logseq/index.md"},x=Object.assign(g,{setup(m){const t=n();return(p,u)=>(l(),r("div",null,[i,e("p",null,[o("3 words, ~0 minute read. "),e("span",{innerHTML:a(s)[`site/${a(t).page.value.relativePath}`]},null,8,_)]),c]))}});export{q as __pageData,x as default}; +import{d as s}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as r,Q as e,K as o,u as a,ag as d,p as l}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"Logseq",-1),_=["innerHTML"],c=d("",3),q=JSON.parse('{"title":"Logseq","description":"","frontmatter":{"public":"true","slug":"logseq","title":"Logseq","prev":false,"next":false},"headers":[],"relativePath":"garden/logseq/index.md","filePath":"garden/logseq/index.md"}'),g={name:"garden/logseq/index.md"},x=Object.assign(g,{setup(m){const t=n();return(p,u)=>(l(),r("div",null,[i,e("p",null,[o("3 words, ~0 minute read. "),e("span",{innerHTML:a(s)[`site/${a(t).page.value.relativePath}`]},null,8,_)]),c]))}});export{q as __pageData,x as default}; diff --git a/assets/garden_matrix_index.md.Cat_AW6q.js b/assets/garden_matrix_index.md.B2azu3Wc.js similarity index 94% rename from assets/garden_matrix_index.md.Cat_AW6q.js rename to assets/garden_matrix_index.md.B2azu3Wc.js index a1f3f8dba..879318430 100644 --- a/assets/garden_matrix_index.md.Cat_AW6q.js +++ b/assets/garden_matrix_index.md.B2azu3Wc.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as s,Q as e,K as i,u as a,ag as d,p as o}from"./chunks/framework.Sr2_9k8k.js";const _=e("h1",{class:"p-name"},"Matrix",-1),m=["innerHTML"],l=d('
Referenced by:CinnyCommuneSynapse

Matrix is a protocol for Decentralized messaging

',3),h=JSON.parse('{"title":"Matrix","description":"","frontmatter":{"public":"true","slug":"matrix","title":"Matrix","prev":false,"next":false},"headers":[],"relativePath":"garden/matrix/index.md","filePath":"garden/matrix/index.md"}'),c={name:"garden/matrix/index.md"},T=Object.assign(c,{setup(p){const t=n();return(u,x)=>(o(),s("div",null,[_,e("p",null,[i("2 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),l]))}});export{h as __pageData,T as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as s,Q as e,K as i,u as a,ag as d,p as o}from"./chunks/framework.Sr2_9k8k.js";const _=e("h1",{class:"p-name"},"Matrix",-1),m=["innerHTML"],l=d('
Referenced by:CinnyCommuneSynapse

Matrix is a protocol for Decentralized messaging

',3),h=JSON.parse('{"title":"Matrix","description":"","frontmatter":{"public":"true","slug":"matrix","title":"Matrix","prev":false,"next":false},"headers":[],"relativePath":"garden/matrix/index.md","filePath":"garden/matrix/index.md"}'),c={name:"garden/matrix/index.md"},T=Object.assign(c,{setup(p){const t=n();return(u,x)=>(o(),s("div",null,[_,e("p",null,[i("2 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),l]))}});export{h as __pageData,T as default}; diff --git a/assets/garden_matrix_index.md.Cat_AW6q.lean.js b/assets/garden_matrix_index.md.B2azu3Wc.lean.js similarity index 91% rename from assets/garden_matrix_index.md.Cat_AW6q.lean.js rename to assets/garden_matrix_index.md.B2azu3Wc.lean.js index a8fc8a870..19f3255c4 100644 --- a/assets/garden_matrix_index.md.Cat_AW6q.lean.js +++ b/assets/garden_matrix_index.md.B2azu3Wc.lean.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as s,Q as e,K as i,u as a,ag as d,p as o}from"./chunks/framework.Sr2_9k8k.js";const _=e("h1",{class:"p-name"},"Matrix",-1),m=["innerHTML"],l=d("",3),h=JSON.parse('{"title":"Matrix","description":"","frontmatter":{"public":"true","slug":"matrix","title":"Matrix","prev":false,"next":false},"headers":[],"relativePath":"garden/matrix/index.md","filePath":"garden/matrix/index.md"}'),c={name:"garden/matrix/index.md"},T=Object.assign(c,{setup(p){const t=n();return(u,x)=>(o(),s("div",null,[_,e("p",null,[i("2 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),l]))}});export{h as __pageData,T as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as s,Q as e,K as i,u as a,ag as d,p as o}from"./chunks/framework.Sr2_9k8k.js";const _=e("h1",{class:"p-name"},"Matrix",-1),m=["innerHTML"],l=d("",3),h=JSON.parse('{"title":"Matrix","description":"","frontmatter":{"public":"true","slug":"matrix","title":"Matrix","prev":false,"next":false},"headers":[],"relativePath":"garden/matrix/index.md","filePath":"garden/matrix/index.md"}'),c={name:"garden/matrix/index.md"},T=Object.assign(c,{setup(p){const t=n();return(u,x)=>(o(),s("div",null,[_,e("p",null,[i("2 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),l]))}});export{h as __pageData,T as default}; diff --git a/assets/garden_mbin_index.md.Bpoe92vo.js b/assets/garden_mbin_index.md.DqnlhoRc.js similarity index 94% rename from assets/garden_mbin_index.md.Bpoe92vo.js rename to assets/garden_mbin_index.md.DqnlhoRc.js index 5979e490f..f0a103164 100644 --- a/assets/garden_mbin_index.md.Bpoe92vo.js +++ b/assets/garden_mbin_index.md.DqnlhoRc.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as i,Q as e,K as t,u as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Mbin",-1),d=["innerHTML"],c=e("hr",null,null,-1),u=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social")],-1),_=e("p",null,[e("a",{href:"https://github.com/MbinOrg/mbin",target:"_blank",rel:"noreferrer"},"Mbin"),t(" is an "),e("a",{href:"/garden/open-source/"},"Open Source"),t(),e("a",{href:"/garden/fediverse/"},"Fediverse"),t(" software")],-1),m=e("p",null,"Can show both twitter-style posts and reddit-style threads",-1),M=JSON.parse('{"title":"Mbin","description":"","frontmatter":{"public":"true","slug":"mbin","title":"Mbin","prev":false,"next":false},"headers":[],"relativePath":"garden/mbin/index.md","filePath":"garden/mbin/index.md"}'),p={name:"garden/mbin/index.md"},v=Object.assign(p,{setup(h){const a=s();return(f,b)=>(l(),i("div",null,[o,e("p",null,[t("12 words, ~0 minute read. "),e("span",{innerHTML:n(r)[`site/${n(a).page.value.relativePath}`]},null,8,d)]),c,u,_,m]))}});export{M as __pageData,v as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as i,Q as e,K as t,u as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Mbin",-1),d=["innerHTML"],c=e("hr",null,null,-1),u=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social")],-1),_=e("p",null,[e("a",{href:"https://github.com/MbinOrg/mbin",target:"_blank",rel:"noreferrer"},"Mbin"),t(" is an "),e("a",{href:"/garden/open-source/"},"Open Source"),t(),e("a",{href:"/garden/fediverse/"},"Fediverse"),t(" software")],-1),m=e("p",null,"Can show both twitter-style posts and reddit-style threads",-1),M=JSON.parse('{"title":"Mbin","description":"","frontmatter":{"public":"true","slug":"mbin","title":"Mbin","prev":false,"next":false},"headers":[],"relativePath":"garden/mbin/index.md","filePath":"garden/mbin/index.md"}'),p={name:"garden/mbin/index.md"},v=Object.assign(p,{setup(h){const a=s();return(f,b)=>(l(),i("div",null,[o,e("p",null,[t("12 words, ~0 minute read. "),e("span",{innerHTML:n(r)[`site/${n(a).page.value.relativePath}`]},null,8,d)]),c,u,_,m]))}});export{M as __pageData,v as default}; diff --git a/assets/garden_mbin_index.md.Bpoe92vo.lean.js b/assets/garden_mbin_index.md.DqnlhoRc.lean.js similarity index 94% rename from assets/garden_mbin_index.md.Bpoe92vo.lean.js rename to assets/garden_mbin_index.md.DqnlhoRc.lean.js index 5979e490f..f0a103164 100644 --- a/assets/garden_mbin_index.md.Bpoe92vo.lean.js +++ b/assets/garden_mbin_index.md.DqnlhoRc.lean.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as i,Q as e,K as t,u as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Mbin",-1),d=["innerHTML"],c=e("hr",null,null,-1),u=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social")],-1),_=e("p",null,[e("a",{href:"https://github.com/MbinOrg/mbin",target:"_blank",rel:"noreferrer"},"Mbin"),t(" is an "),e("a",{href:"/garden/open-source/"},"Open Source"),t(),e("a",{href:"/garden/fediverse/"},"Fediverse"),t(" software")],-1),m=e("p",null,"Can show both twitter-style posts and reddit-style threads",-1),M=JSON.parse('{"title":"Mbin","description":"","frontmatter":{"public":"true","slug":"mbin","title":"Mbin","prev":false,"next":false},"headers":[],"relativePath":"garden/mbin/index.md","filePath":"garden/mbin/index.md"}'),p={name:"garden/mbin/index.md"},v=Object.assign(p,{setup(h){const a=s();return(f,b)=>(l(),i("div",null,[o,e("p",null,[t("12 words, ~0 minute read. "),e("span",{innerHTML:n(r)[`site/${n(a).page.value.relativePath}`]},null,8,d)]),c,u,_,m]))}});export{M as __pageData,v as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as i,Q as e,K as t,u as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Mbin",-1),d=["innerHTML"],c=e("hr",null,null,-1),u=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social")],-1),_=e("p",null,[e("a",{href:"https://github.com/MbinOrg/mbin",target:"_blank",rel:"noreferrer"},"Mbin"),t(" is an "),e("a",{href:"/garden/open-source/"},"Open Source"),t(),e("a",{href:"/garden/fediverse/"},"Fediverse"),t(" software")],-1),m=e("p",null,"Can show both twitter-style posts and reddit-style threads",-1),M=JSON.parse('{"title":"Mbin","description":"","frontmatter":{"public":"true","slug":"mbin","title":"Mbin","prev":false,"next":false},"headers":[],"relativePath":"garden/mbin/index.md","filePath":"garden/mbin/index.md"}'),p={name:"garden/mbin/index.md"},v=Object.assign(p,{setup(h){const a=s();return(f,b)=>(l(),i("div",null,[o,e("p",null,[t("12 words, ~0 minute read. "),e("span",{innerHTML:n(r)[`site/${n(a).page.value.relativePath}`]},null,8,d)]),c,u,_,m]))}});export{M as __pageData,v as default}; diff --git a/assets/garden_moderation_index.md.BM0rdbL6.js b/assets/garden_moderation_index.md.B7RP_VZ_.js similarity index 98% rename from assets/garden_moderation_index.md.BM0rdbL6.js rename to assets/garden_moderation_index.md.B7RP_VZ_.js index b75088edf..f35e32a09 100644 --- a/assets/garden_moderation_index.md.BM0rdbL6.js +++ b/assets/garden_moderation_index.md.B7RP_VZ_.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as i,Q as e,K as s,u as t,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Moderation",-1),d=["innerHTML"],c=n('
Referenced by:Decentralized Moderation

Moderation, in the context of Social Media, is the enforcement of rules by removing offending content, and optionally punishing the offender through silencing, banning, or other measures.

What these rules are will typically vary platform to platform, and sometimes even community to community. This stems from different communities having different purposes or goals, along with differing views on what is acceptable speech. For example, a forums for victims of abuse may feature very heavy moderation, or a community for Christians may limit joining the community to only fellow Christians.

Free Speech

Some platforms try to be very light handed with their moderation, often arguing that infringing on speech is inherently censorship and must be avoided unless it's literally against the law to say. These people are called "Free Speech Absolutists". In practice, most of those advocating for free speech absolutism are just fine censoring speech they disagree with, such as Elon Musk. He has been biased towards his personal views and self interests both in deciding which government censorship requests X complies with and promoting his own posts above others.

In general, those arguing for less moderation or more free speech are doing so from a position of privilege. In traditional social media, those with more power have more speech (that is, they're more influential), so arguing for free speech is perpetuating the existing power dynamics by giving them lots of speech and removing the ability for more fringe groups to have that hateful content removed. The fringe may criticize, but that won't likely be enough to change anything, as their calls to deplatform those in the ruling class are stymied by arguments for free speech.

However, these concerns regarding free speech would likely be mostly mitigated by Decentralized Social Media and may lead to overall more lax rules in social media with Decentralized Moderation.

Blocklists

Blocklists are lists of users someone has blocked, that they then share with the public. Some blocklists even auto update as the creator adds new users to them.

Blocklists are a double edged sword. They can help, for example, marginalized communities block those who wish them harm regularly. However, they centralize power and are often abused. I recommend this article which discusses blocklists and how they help and how they harm, especially with respect to marginalized communities.

',11),w=JSON.parse('{"title":"Moderation","description":"","frontmatter":{"alias":"Moderate","public":"true","slug":"moderation","title":"Moderation","prev":false,"next":false},"headers":[],"relativePath":"garden/moderation/index.md","filePath":"garden/moderation/index.md"}'),m={name:"garden/moderation/index.md"},b=Object.assign(m,{setup(p){const a=o();return(f,u)=>(l(),i("div",null,[h,e("p",null,[s("365 words, ~2 minute read. "),e("span",{innerHTML:t(r)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),c]))}});export{w as __pageData,b as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as i,Q as e,K as s,u as t,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Moderation",-1),d=["innerHTML"],c=n('
Referenced by:Decentralized Moderation

Moderation, in the context of Social Media, is the enforcement of rules by removing offending content, and optionally punishing the offender through silencing, banning, or other measures.

What these rules are will typically vary platform to platform, and sometimes even community to community. This stems from different communities having different purposes or goals, along with differing views on what is acceptable speech. For example, a forums for victims of abuse may feature very heavy moderation, or a community for Christians may limit joining the community to only fellow Christians.

Free Speech

Some platforms try to be very light handed with their moderation, often arguing that infringing on speech is inherently censorship and must be avoided unless it's literally against the law to say. These people are called "Free Speech Absolutists". In practice, most of those advocating for free speech absolutism are just fine censoring speech they disagree with, such as Elon Musk. He has been biased towards his personal views and self interests both in deciding which government censorship requests X complies with and promoting his own posts above others.

In general, those arguing for less moderation or more free speech are doing so from a position of privilege. In traditional social media, those with more power have more speech (that is, they're more influential), so arguing for free speech is perpetuating the existing power dynamics by giving them lots of speech and removing the ability for more fringe groups to have that hateful content removed. The fringe may criticize, but that won't likely be enough to change anything, as their calls to deplatform those in the ruling class are stymied by arguments for free speech.

However, these concerns regarding free speech would likely be mostly mitigated by Decentralized Social Media and may lead to overall more lax rules in social media with Decentralized Moderation.

Blocklists

Blocklists are lists of users someone has blocked, that they then share with the public. Some blocklists even auto update as the creator adds new users to them.

Blocklists are a double edged sword. They can help, for example, marginalized communities block those who wish them harm regularly. However, they centralize power and are often abused. I recommend this article which discusses blocklists and how they help and how they harm, especially with respect to marginalized communities.

',11),w=JSON.parse('{"title":"Moderation","description":"","frontmatter":{"alias":"Moderate","public":"true","slug":"moderation","title":"Moderation","prev":false,"next":false},"headers":[],"relativePath":"garden/moderation/index.md","filePath":"garden/moderation/index.md"}'),m={name:"garden/moderation/index.md"},b=Object.assign(m,{setup(p){const a=o();return(f,u)=>(l(),i("div",null,[h,e("p",null,[s("365 words, ~2 minute read. "),e("span",{innerHTML:t(r)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),c]))}});export{w as __pageData,b as default}; diff --git a/assets/garden_moderation_index.md.BM0rdbL6.lean.js b/assets/garden_moderation_index.md.B7RP_VZ_.lean.js similarity index 91% rename from assets/garden_moderation_index.md.BM0rdbL6.lean.js rename to assets/garden_moderation_index.md.B7RP_VZ_.lean.js index 70ae669af..cf2d231a9 100644 --- a/assets/garden_moderation_index.md.BM0rdbL6.lean.js +++ b/assets/garden_moderation_index.md.B7RP_VZ_.lean.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as i,Q as e,K as s,u as t,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Moderation",-1),d=["innerHTML"],c=n("",11),w=JSON.parse('{"title":"Moderation","description":"","frontmatter":{"alias":"Moderate","public":"true","slug":"moderation","title":"Moderation","prev":false,"next":false},"headers":[],"relativePath":"garden/moderation/index.md","filePath":"garden/moderation/index.md"}'),m={name:"garden/moderation/index.md"},b=Object.assign(m,{setup(p){const a=o();return(f,u)=>(l(),i("div",null,[h,e("p",null,[s("365 words, ~2 minute read. "),e("span",{innerHTML:t(r)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),c]))}});export{w as __pageData,b as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as i,Q as e,K as s,u as t,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Moderation",-1),d=["innerHTML"],c=n("",11),w=JSON.parse('{"title":"Moderation","description":"","frontmatter":{"alias":"Moderate","public":"true","slug":"moderation","title":"Moderation","prev":false,"next":false},"headers":[],"relativePath":"garden/moderation/index.md","filePath":"garden/moderation/index.md"}'),m={name:"garden/moderation/index.md"},b=Object.assign(m,{setup(p){const a=o();return(f,u)=>(l(),i("div",null,[h,e("p",null,[s("365 words, ~2 minute read. "),e("span",{innerHTML:t(r)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),c]))}});export{w as __pageData,b as default}; diff --git a/assets/garden_mtx_index.md.BbdJq7Ny.js b/assets/garden_mtx_index.md.BsaqlBYK.js similarity index 93% rename from assets/garden_mtx_index.md.BbdJq7Ny.js rename to assets/garden_mtx_index.md.BsaqlBYK.js index 746e1f8bc..59a5915d1 100644 --- a/assets/garden_mtx_index.md.BbdJq7Ny.js +++ b/assets/garden_mtx_index.md.BsaqlBYK.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as r,Q as e,K as i,u as a,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"MTX",-1),d=["innerHTML"],c=e("hr",null,null,-1),m=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/premium-currency/index.md"},"Premium Currency"),e("a",{href:"/garden/video-game-monetization/index.md"},"Video Game Monetization")],-1),u=e("p",null,"Purchaseable items in video games that cost real life currencies",-1),M=JSON.parse('{"title":"MTX","description":"","frontmatter":{"alias":"Microtransactions, IAP, In-App Purchases","public":"true","slug":"mtx","title":"MTX","prev":false,"next":false},"headers":[],"relativePath":"garden/mtx/index.md","filePath":"garden/mtx/index.md"}'),p={name:"garden/mtx/index.md"},v=Object.assign(p,{setup(_){const t=s();return(h,f)=>(o(),r("div",null,[l,e("p",null,[i("10 words, ~0 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),c,m,u]))}});export{M as __pageData,v as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as r,Q as e,K as i,u as a,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"MTX",-1),d=["innerHTML"],c=e("hr",null,null,-1),m=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/premium-currency/index.md"},"Premium Currency"),e("a",{href:"/garden/video-game-monetization/index.md"},"Video Game Monetization")],-1),u=e("p",null,"Purchaseable items in video games that cost real life currencies",-1),M=JSON.parse('{"title":"MTX","description":"","frontmatter":{"alias":"Microtransactions, IAP, In-App Purchases","public":"true","slug":"mtx","title":"MTX","prev":false,"next":false},"headers":[],"relativePath":"garden/mtx/index.md","filePath":"garden/mtx/index.md"}'),p={name:"garden/mtx/index.md"},v=Object.assign(p,{setup(_){const t=s();return(h,f)=>(o(),r("div",null,[l,e("p",null,[i("10 words, ~0 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),c,m,u]))}});export{M as __pageData,v as default}; diff --git a/assets/garden_mtx_index.md.BbdJq7Ny.lean.js b/assets/garden_mtx_index.md.BsaqlBYK.lean.js similarity index 93% rename from assets/garden_mtx_index.md.BbdJq7Ny.lean.js rename to assets/garden_mtx_index.md.BsaqlBYK.lean.js index 746e1f8bc..59a5915d1 100644 --- a/assets/garden_mtx_index.md.BbdJq7Ny.lean.js +++ b/assets/garden_mtx_index.md.BsaqlBYK.lean.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as r,Q as e,K as i,u as a,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"MTX",-1),d=["innerHTML"],c=e("hr",null,null,-1),m=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/premium-currency/index.md"},"Premium Currency"),e("a",{href:"/garden/video-game-monetization/index.md"},"Video Game Monetization")],-1),u=e("p",null,"Purchaseable items in video games that cost real life currencies",-1),M=JSON.parse('{"title":"MTX","description":"","frontmatter":{"alias":"Microtransactions, IAP, In-App Purchases","public":"true","slug":"mtx","title":"MTX","prev":false,"next":false},"headers":[],"relativePath":"garden/mtx/index.md","filePath":"garden/mtx/index.md"}'),p={name:"garden/mtx/index.md"},v=Object.assign(p,{setup(_){const t=s();return(h,f)=>(o(),r("div",null,[l,e("p",null,[i("10 words, ~0 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),c,m,u]))}});export{M as __pageData,v as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as r,Q as e,K as i,u as a,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"MTX",-1),d=["innerHTML"],c=e("hr",null,null,-1),m=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/premium-currency/index.md"},"Premium Currency"),e("a",{href:"/garden/video-game-monetization/index.md"},"Video Game Monetization")],-1),u=e("p",null,"Purchaseable items in video games that cost real life currencies",-1),M=JSON.parse('{"title":"MTX","description":"","frontmatter":{"alias":"Microtransactions, IAP, In-App Purchases","public":"true","slug":"mtx","title":"MTX","prev":false,"next":false},"headers":[],"relativePath":"garden/mtx/index.md","filePath":"garden/mtx/index.md"}'),p={name:"garden/mtx/index.md"},v=Object.assign(p,{setup(_){const t=s();return(h,f)=>(o(),r("div",null,[l,e("p",null,[i("10 words, ~0 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),c,m,u]))}});export{M as __pageData,v as default}; diff --git a/assets/garden_my-browser-stack_index.md.DCchRRYs.js b/assets/garden_my-browser-stack_index.md.uksLZ895.js similarity index 98% rename from assets/garden_my-browser-stack_index.md.DCchRRYs.js rename to assets/garden_my-browser-stack_index.md.uksLZ895.js index 0615633a6..ad16eb012 100644 --- a/assets/garden_my-browser-stack_index.md.DCchRRYs.js +++ b/assets/garden_my-browser-stack_index.md.uksLZ895.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as n,Q as e,K as i,u as r,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"My Browser Stack",-1),h=["innerHTML"],u=s('

This is the list of tools I use for browsing the internet in a safe way that ensures it's a pleasant experience.

Browser

I've used a lot of browsers over time, and currently use Zen because of it's modern look. At this point I really just recommend any fork of Firefox (such as Zen). Mozilla has seen its fair share of controversy, but nowhere near the amount Google has, and it's worth using a Firefox based browser in order to fight the chrome monopoly.

Other great Firefox forks to look at are librewolf and waterfox, which are privacy centric and lightweight and run faster than stock firefox.

Extensions

A classic recommendation you've probably already heard, uBlock Origin is a requirement for browsing the internet. Ads spy on you and significantly degrade your browsing experience, and this extension fixes that. Gorhill, it's creator, deserves so much appreciation for the service they've done to the entire world.

Youtube

If you browse YouTube in your browser, you might be interested in these extensions as well:

Sponsorblock uses crowd sourced information on YouTube videos to automatically skip past parts you don't care about, like sponsor reads or calls to like or subscribe.

DeArrow uses crowd sourced information on YouTube videos to replace the original titles with more descriptive ones (to avoid click bait). It'll also replace thumbnails with random frames from the video itself. Note this extension asks for a $1 donation or to request free access, which can take a few hours (but you can "trial" the extension in the meantime).

With the advent of AI generated content, it has become much more difficult to search the web. Here's some techniques to find useful, original, human made resources.

If you'd like to clean up your mainstream search engine results(Google, DuckDuckGo, or Bing), you can use the Huge AI Blocklist. The list works with uBlock Origin, but they recommend using uBlacklist, an extension specifically for blocking certain Google search results.

If you're willing to pay, Kagi is a premium search engine you may be interested in. Being a paid service, it doesn't rely on ads or tracking to make a profit, and has a great reputation for high quality results and additional features free search engines don't have like personalized rankings for domains.

There is also an independent search engine called Marginalia that designed to show you non commercialized sites that are typically smaller and independent, which acts as a great filter to only see human made resources.

Finally, if your goal is just privacy, the extension mentioned in the following section will help redirect you to alternative search engines as well.

Privacy respecting front ends

There are many projects out there that offer sites you can go to that interface with popular but not privacy respecting websites like YouTube or Twitter. This is personally a bit overkill for me, but I've considered using them in the past. Rather than looking up each alternative directly and finding a working instance, I recommend just using a regularly maintained extension that automatically redirects you from the popular site to a working instance of the alternative frontend, like Privacy Redirect.

',19),y=JSON.parse('{"title":"My Browser Stack","description":"","frontmatter":{"public":"true","slug":"my-browser-stack","title":"My Browser Stack","prev":false,"next":false},"headers":[],"relativePath":"garden/my-browser-stack/index.md","filePath":"garden/my-browser-stack/index.md"}'),d={name:"garden/my-browser-stack/index.md"},k=Object.assign(d,{setup(p){const a=o();return(f,m)=>(l(),n("div",null,[c,e("p",null,[i("447 words, ~2 minute read. "),e("span",{innerHTML:r(t)[`site/${r(a).page.value.relativePath}`]},null,8,h)]),u]))}});export{y as __pageData,k as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as n,Q as e,K as i,u as r,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"My Browser Stack",-1),h=["innerHTML"],u=s('

This is the list of tools I use for browsing the internet in a safe way that ensures it's a pleasant experience.

Browser

I've used a lot of browsers over time, and currently use Zen because of it's modern look. At this point I really just recommend any fork of Firefox (such as Zen). Mozilla has seen its fair share of controversy, but nowhere near the amount Google has, and it's worth using a Firefox based browser in order to fight the chrome monopoly.

Other great Firefox forks to look at are librewolf and waterfox, which are privacy centric and lightweight and run faster than stock firefox.

Extensions

A classic recommendation you've probably already heard, uBlock Origin is a requirement for browsing the internet. Ads spy on you and significantly degrade your browsing experience, and this extension fixes that. Gorhill, it's creator, deserves so much appreciation for the service they've done to the entire world.

Youtube

If you browse YouTube in your browser, you might be interested in these extensions as well:

Sponsorblock uses crowd sourced information on YouTube videos to automatically skip past parts you don't care about, like sponsor reads or calls to like or subscribe.

DeArrow uses crowd sourced information on YouTube videos to replace the original titles with more descriptive ones (to avoid click bait). It'll also replace thumbnails with random frames from the video itself. Note this extension asks for a $1 donation or to request free access, which can take a few hours (but you can "trial" the extension in the meantime).

With the advent of AI generated content, it has become much more difficult to search the web. Here's some techniques to find useful, original, human made resources.

If you'd like to clean up your mainstream search engine results(Google, DuckDuckGo, or Bing), you can use the Huge AI Blocklist. The list works with uBlock Origin, but they recommend using uBlacklist, an extension specifically for blocking certain Google search results.

If you're willing to pay, Kagi is a premium search engine you may be interested in. Being a paid service, it doesn't rely on ads or tracking to make a profit, and has a great reputation for high quality results and additional features free search engines don't have like personalized rankings for domains.

There is also an independent search engine called Marginalia that designed to show you non commercialized sites that are typically smaller and independent, which acts as a great filter to only see human made resources.

Finally, if your goal is just privacy, the extension mentioned in the following section will help redirect you to alternative search engines as well.

Privacy respecting front ends

There are many projects out there that offer sites you can go to that interface with popular but not privacy respecting websites like YouTube or Twitter. This is personally a bit overkill for me, but I've considered using them in the past. Rather than looking up each alternative directly and finding a working instance, I recommend just using a regularly maintained extension that automatically redirects you from the popular site to a working instance of the alternative frontend, like Privacy Redirect.

',19),y=JSON.parse('{"title":"My Browser Stack","description":"","frontmatter":{"public":"true","slug":"my-browser-stack","title":"My Browser Stack","prev":false,"next":false},"headers":[],"relativePath":"garden/my-browser-stack/index.md","filePath":"garden/my-browser-stack/index.md"}'),d={name:"garden/my-browser-stack/index.md"},k=Object.assign(d,{setup(p){const a=o();return(f,m)=>(l(),n("div",null,[c,e("p",null,[i("447 words, ~2 minute read. "),e("span",{innerHTML:r(t)[`site/${r(a).page.value.relativePath}`]},null,8,h)]),u]))}});export{y as __pageData,k as default}; diff --git a/assets/garden_my-browser-stack_index.md.DCchRRYs.lean.js b/assets/garden_my-browser-stack_index.md.uksLZ895.lean.js similarity index 91% rename from assets/garden_my-browser-stack_index.md.DCchRRYs.lean.js rename to assets/garden_my-browser-stack_index.md.uksLZ895.lean.js index cfc2f68e9..335d55025 100644 --- a/assets/garden_my-browser-stack_index.md.DCchRRYs.lean.js +++ b/assets/garden_my-browser-stack_index.md.uksLZ895.lean.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as n,Q as e,K as i,u as r,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"My Browser Stack",-1),h=["innerHTML"],u=s("",19),y=JSON.parse('{"title":"My Browser Stack","description":"","frontmatter":{"public":"true","slug":"my-browser-stack","title":"My Browser Stack","prev":false,"next":false},"headers":[],"relativePath":"garden/my-browser-stack/index.md","filePath":"garden/my-browser-stack/index.md"}'),d={name:"garden/my-browser-stack/index.md"},k=Object.assign(d,{setup(p){const a=o();return(f,m)=>(l(),n("div",null,[c,e("p",null,[i("447 words, ~2 minute read. "),e("span",{innerHTML:r(t)[`site/${r(a).page.value.relativePath}`]},null,8,h)]),u]))}});export{y as __pageData,k as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as n,Q as e,K as i,u as r,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"My Browser Stack",-1),h=["innerHTML"],u=s("",19),y=JSON.parse('{"title":"My Browser Stack","description":"","frontmatter":{"public":"true","slug":"my-browser-stack","title":"My Browser Stack","prev":false,"next":false},"headers":[],"relativePath":"garden/my-browser-stack/index.md","filePath":"garden/my-browser-stack/index.md"}'),d={name:"garden/my-browser-stack/index.md"},k=Object.assign(d,{setup(p){const a=o();return(f,m)=>(l(),n("div",null,[c,e("p",null,[i("447 words, ~2 minute read. "),e("span",{innerHTML:r(t)[`site/${r(a).page.value.relativePath}`]},null,8,h)]),u]))}});export{y as __pageData,k as default}; diff --git a/assets/garden_my-personal-website_index.md.DLhI2FKw.js b/assets/garden_my-personal-website_index.md.D9RxR9Ge.js similarity index 98% rename from assets/garden_my-personal-website_index.md.DLhI2FKw.js rename to assets/garden_my-personal-website_index.md.D9RxR9Ge.js index cd11e3bb8..f26a5d349 100644 --- a/assets/garden_my-personal-website_index.md.DLhI2FKw.js +++ b/assets/garden_my-personal-website_index.md.D9RxR9Ge.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as l,Q as e,K as i,u as a,ag as o,p as n}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"My Personal Website",-1),h=["innerHTML"],p=o('
Referenced by:The Small WebThis Knowledge Hub

A Personal Websites for myself, available at https://thepaperpilot.org

Tech Stack

I use Logseq to journal and collect my thoughts on various topics that interest me

  • Seafile syncs my logseq files between my devices
  • Git syncs my logseq files to a private repo on Incremental Social for purposes of version control and using as a submodule
  • The seafile files and all repos on Incremental Social are independently backed up daily to backblaze

My logseq files are synced to a private git repo which is added as a submodule to my website repo

A Node.js script pre-processes my logseq files into markdown files in the /garden path of the website

  • Converts all links and block references
  • Adds lists of tags and references to pages
  • Adds <h1 /> titles, word counts, update commits, etc. to each page
  • Moves the /now page to /now instead of /garden/now
  • Copies some of the Guide to Incrementals pages to /guide-to-incrementals so as to not break links made before the current site iteration
  • Generates /changelog and its RSS, Atom, and JSON feeds
    • The outputs of the generation are NOT .gitignore'd, as I use the git log to determine which pages updated when - Commit information about when a file was last updated is added via a data loader because if it was added to the file directly, rebuilding the site would count as having updated every page, by updating each commit to the changes introduced last build

Vitepress builds a static site from the markdown files

  • Includes a custom theme that makes the whole site paper-themed
  • Includes some pages like the homepage and the about me page that require markup, thus don't make sense to maintain inside logseq
  • The sidebar is generated from my favorited pages within Logseq
  • Includes various static files, like copies of several of my games and a robots.txt (borrowed from Tracy Durnell's robots.txt) that blocks several crawlers specifically used for training AI models

Three.js is used to create the effect in the background

  • Simplex noise gets used to adjust the opacity of a repeating SVG pattern
  • Initially tried to use just SVG, which supports creating noise and using it as a mask, but it only does 2d noise and I need 2d slices of 3d noise

Microformats are used to markup the site for The IndieWeb

  • The footer contains a minimal h-card with a link to my full profile
  • Each garden page is an h-entry, and the changelog an h-feed
  • All my socials are added as rel-me links, and the profiles then link back to me (as rel-me links, if allowed by the platform)
    • Together this can verify the owner of this website and those socials are the same person
',15),k=JSON.parse('{"title":"My Personal Website","description":"","frontmatter":{"public":"true","slug":"my-personal-website","title":"My Personal Website","prev":false,"next":false},"headers":[],"relativePath":"garden/my-personal-website/index.md","filePath":"garden/my-personal-website/index.md"}'),c={name:"garden/my-personal-website/index.md"},_=Object.assign(c,{setup(g){const t=s();return(f,m)=>(n(),l("div",null,[d,e("p",null,[i("422 words, ~2 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,h)]),p]))}});export{k as __pageData,_ as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as l,Q as e,K as i,u as a,ag as o,p as n}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"My Personal Website",-1),h=["innerHTML"],p=o('
Referenced by:The Small WebThis Knowledge Hub

A Personal Websites for myself, available at https://thepaperpilot.org

Tech Stack

I use Logseq to journal and collect my thoughts on various topics that interest me

  • Seafile syncs my logseq files between my devices
  • Git syncs my logseq files to a private repo on Incremental Social for purposes of version control and using as a submodule
  • The seafile files and all repos on Incremental Social are independently backed up daily to backblaze

My logseq files are synced to a private git repo which is added as a submodule to my website repo

A Node.js script pre-processes my logseq files into markdown files in the /garden path of the website

  • Converts all links and block references
  • Adds lists of tags and references to pages
  • Adds <h1 /> titles, word counts, update commits, etc. to each page
  • Moves the /now page to /now instead of /garden/now
  • Copies some of the Guide to Incrementals pages to /guide-to-incrementals so as to not break links made before the current site iteration
  • Generates /changelog and its RSS, Atom, and JSON feeds
    • The outputs of the generation are NOT .gitignore'd, as I use the git log to determine which pages updated when - Commit information about when a file was last updated is added via a data loader because if it was added to the file directly, rebuilding the site would count as having updated every page, by updating each commit to the changes introduced last build

Vitepress builds a static site from the markdown files

  • Includes a custom theme that makes the whole site paper-themed
  • Includes some pages like the homepage and the about me page that require markup, thus don't make sense to maintain inside logseq
  • The sidebar is generated from my favorited pages within Logseq
  • Includes various static files, like copies of several of my games and a robots.txt (borrowed from Tracy Durnell's robots.txt) that blocks several crawlers specifically used for training AI models

Three.js is used to create the effect in the background

  • Simplex noise gets used to adjust the opacity of a repeating SVG pattern
  • Initially tried to use just SVG, which supports creating noise and using it as a mask, but it only does 2d noise and I need 2d slices of 3d noise

Microformats are used to markup the site for The IndieWeb

  • The footer contains a minimal h-card with a link to my full profile
  • Each garden page is an h-entry, and the changelog an h-feed
  • All my socials are added as rel-me links, and the profiles then link back to me (as rel-me links, if allowed by the platform)
    • Together this can verify the owner of this website and those socials are the same person
',15),k=JSON.parse('{"title":"My Personal Website","description":"","frontmatter":{"public":"true","slug":"my-personal-website","title":"My Personal Website","prev":false,"next":false},"headers":[],"relativePath":"garden/my-personal-website/index.md","filePath":"garden/my-personal-website/index.md"}'),c={name:"garden/my-personal-website/index.md"},_=Object.assign(c,{setup(g){const t=s();return(f,m)=>(n(),l("div",null,[d,e("p",null,[i("422 words, ~2 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,h)]),p]))}});export{k as __pageData,_ as default}; diff --git a/assets/garden_my-personal-website_index.md.DLhI2FKw.lean.js b/assets/garden_my-personal-website_index.md.D9RxR9Ge.lean.js similarity index 92% rename from assets/garden_my-personal-website_index.md.DLhI2FKw.lean.js rename to assets/garden_my-personal-website_index.md.D9RxR9Ge.lean.js index 92f4f52c1..3620d77c5 100644 --- a/assets/garden_my-personal-website_index.md.DLhI2FKw.lean.js +++ b/assets/garden_my-personal-website_index.md.D9RxR9Ge.lean.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as l,Q as e,K as i,u as a,ag as o,p as n}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"My Personal Website",-1),h=["innerHTML"],p=o("",15),k=JSON.parse('{"title":"My Personal Website","description":"","frontmatter":{"public":"true","slug":"my-personal-website","title":"My Personal Website","prev":false,"next":false},"headers":[],"relativePath":"garden/my-personal-website/index.md","filePath":"garden/my-personal-website/index.md"}'),c={name:"garden/my-personal-website/index.md"},_=Object.assign(c,{setup(g){const t=s();return(f,m)=>(n(),l("div",null,[d,e("p",null,[i("422 words, ~2 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,h)]),p]))}});export{k as __pageData,_ as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as l,Q as e,K as i,u as a,ag as o,p as n}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"My Personal Website",-1),h=["innerHTML"],p=o("",15),k=JSON.parse('{"title":"My Personal Website","description":"","frontmatter":{"public":"true","slug":"my-personal-website","title":"My Personal Website","prev":false,"next":false},"headers":[],"relativePath":"garden/my-personal-website/index.md","filePath":"garden/my-personal-website/index.md"}'),c={name:"garden/my-personal-website/index.md"},_=Object.assign(c,{setup(g){const t=s();return(f,m)=>(n(),l("div",null,[d,e("p",null,[i("422 words, ~2 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,h)]),p]))}});export{k as __pageData,_ as default}; diff --git a/assets/garden_my-political-beliefs_index.md.BOiL5pI1.js b/assets/garden_my-political-beliefs_index.md.BYXcV_fb.js similarity index 97% rename from assets/garden_my-political-beliefs_index.md.BOiL5pI1.js rename to assets/garden_my-political-beliefs_index.md.BYXcV_fb.js index 0c34caf32..738117a21 100644 --- a/assets/garden_my-political-beliefs_index.md.BOiL5pI1.js +++ b/assets/garden_my-political-beliefs_index.md.BYXcV_fb.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as o,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"My Political Beliefs",-1),d=["innerHTML"],m=s('
Referenced by:My Political JourneyPolitical Quizzes

Government

I'm definitely a Leftist, and believe our end goal should be a classless, stateless, moneyless society, but acknowledge the role of the state in defending against, at the very least, Imperialist forces abroad, so long as they exist.

I want to eventually reach a society structured as decentralized local communities that operate through Consensus Democracy , and freely associate with other communities for larger scale organizing, such as building and maintaining a rail line.

Economy

I believe we should eventually arrive at communism; a post-scarcity society where everyone's needs are met via automation and without the need for currency. Along the way there I expect us to democratize the workplace and work towards nationalizing every idustry.

Society

I believe in maximizing personal liberties, so long as one is not actively harmful to others, including most forms of discrimination.

Security

I'm against the use of violence by anyone, including the state. I believe in Police Abolition and am against the military and espionage both foreign and domestic. I believe in the Anarchist value of free association, so I believe we should have fully open borders, both for travel and immigration/emigration. I am anti-imperialist and believe in a fairly isolationist foreign policy, but am not against humanitarian foreign aid.

',11),b=JSON.parse('{"title":"My Political Beliefs","description":"","frontmatter":{"public":"true","slug":"my-political-beliefs","title":"My Political Beliefs","prev":false,"next":false},"headers":[],"relativePath":"garden/my-political-beliefs/index.md","filePath":"garden/my-political-beliefs/index.md"}'),h={name:"garden/my-political-beliefs/index.md"},_=Object.assign(h,{setup(u){const i=n();return(y,f)=>(l(),o("div",null,[c,e("p",null,[r("213 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(i).page.value.relativePath}`]},null,8,d)]),m]))}});export{b as __pageData,_ as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as o,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"My Political Beliefs",-1),d=["innerHTML"],m=s('
Referenced by:My Political JourneyPolitical Quizzes

Government

I'm definitely a Leftist, and believe our end goal should be a classless, stateless, moneyless society, but acknowledge the role of the state in defending against, at the very least, Imperialist forces abroad, so long as they exist.

I want to eventually reach a society structured as decentralized local communities that operate through Consensus Democracy , and freely associate with other communities for larger scale organizing, such as building and maintaining a rail line.

Economy

I believe we should eventually arrive at communism; a post-scarcity society where everyone's needs are met via automation and without the need for currency. Along the way there I expect us to democratize the workplace and work towards nationalizing every idustry.

Society

I believe in maximizing personal liberties, so long as one is not actively harmful to others, including most forms of discrimination.

Security

I'm against the use of violence by anyone, including the state. I believe in Police Abolition and am against the military and espionage both foreign and domestic. I believe in the Anarchist value of free association, so I believe we should have fully open borders, both for travel and immigration/emigration. I am anti-imperialist and believe in a fairly isolationist foreign policy, but am not against humanitarian foreign aid.

',11),b=JSON.parse('{"title":"My Political Beliefs","description":"","frontmatter":{"public":"true","slug":"my-political-beliefs","title":"My Political Beliefs","prev":false,"next":false},"headers":[],"relativePath":"garden/my-political-beliefs/index.md","filePath":"garden/my-political-beliefs/index.md"}'),h={name:"garden/my-political-beliefs/index.md"},_=Object.assign(h,{setup(u){const i=n();return(y,f)=>(l(),o("div",null,[c,e("p",null,[r("213 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(i).page.value.relativePath}`]},null,8,d)]),m]))}});export{b as __pageData,_ as default}; diff --git a/assets/garden_my-political-beliefs_index.md.BOiL5pI1.lean.js b/assets/garden_my-political-beliefs_index.md.BYXcV_fb.lean.js similarity index 92% rename from assets/garden_my-political-beliefs_index.md.BOiL5pI1.lean.js rename to assets/garden_my-political-beliefs_index.md.BYXcV_fb.lean.js index be2c42e28..6c5b0dd1b 100644 --- a/assets/garden_my-political-beliefs_index.md.BOiL5pI1.lean.js +++ b/assets/garden_my-political-beliefs_index.md.BYXcV_fb.lean.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as o,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"My Political Beliefs",-1),d=["innerHTML"],m=s("",11),b=JSON.parse('{"title":"My Political Beliefs","description":"","frontmatter":{"public":"true","slug":"my-political-beliefs","title":"My Political Beliefs","prev":false,"next":false},"headers":[],"relativePath":"garden/my-political-beliefs/index.md","filePath":"garden/my-political-beliefs/index.md"}'),h={name:"garden/my-political-beliefs/index.md"},_=Object.assign(h,{setup(u){const i=n();return(y,f)=>(l(),o("div",null,[c,e("p",null,[r("213 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(i).page.value.relativePath}`]},null,8,d)]),m]))}});export{b as __pageData,_ as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as o,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"My Political Beliefs",-1),d=["innerHTML"],m=s("",11),b=JSON.parse('{"title":"My Political Beliefs","description":"","frontmatter":{"public":"true","slug":"my-political-beliefs","title":"My Political Beliefs","prev":false,"next":false},"headers":[],"relativePath":"garden/my-political-beliefs/index.md","filePath":"garden/my-political-beliefs/index.md"}'),h={name:"garden/my-political-beliefs/index.md"},_=Object.assign(h,{setup(u){const i=n();return(y,f)=>(l(),o("div",null,[c,e("p",null,[r("213 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(i).page.value.relativePath}`]},null,8,d)]),m]))}});export{b as __pageData,_ as default}; diff --git a/assets/garden_my-political-journey_index.md.D7DllfwU.js b/assets/garden_my-political-journey_index.md.BXr8MFu7.js similarity index 99% rename from assets/garden_my-political-journey_index.md.D7DllfwU.js rename to assets/garden_my-political-journey_index.md.BXr8MFu7.js index d8d6d522e..bb02aaa90 100644 --- a/assets/garden_my-political-journey_index.md.D7DllfwU.js +++ b/assets/garden_my-political-journey_index.md.BXr8MFu7.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as n,Q as e,K as r,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"My Political Journey",-1),d=["innerHTML"],c=s('
Referenced by:LeftismPolitical Quizzes

My Political Beliefs have changed over time, although I believe it mostly stems from me becoming increasingly informed. Since this website contains content from as far back as 2006, when I was only 10 years old, I'd like to make it extremely clear that I have changed as a person, as we all have, and disavow a lot of my older opinions, roughly everything before 2020 or so but to be safe let's just give a dynamic (current date - 2 years). It's likely you are on this page from viewing a timeline post from that range and clicking the banner. There are bits in that period I may still agree with, but perhaps it would be best to just assume I don't have a stance on it unless there's something more recent about it. Pages in the garden section of this site are evergreen though, meaning I'll keep them up to date as my views change. Feel completely free to judge me for my opinions in there.

Core beliefs

I believe I've been fairly political since I was quite young, and had a relatively consistent set of core values that have just been expressed in different ways and through different lenses during different points of my life. For example I've always believed in fairness, but have used that belief to both argue for and against affirmative action. Concepts like freedom or meritocracies have similarly been redefined as I've become more aware of the influence of imperialism and colonialism on our cultural values and society.

Other beliefs of mine have always been around, but I just wasn't informed enough to properly express my views. I've voiced for a very long time that I think society will inevitably trend towards post-scarcity, a world without class, currency, or jobs, where all our needs and desires are met fully, automatically, and sustainably. I've never once pictured that society retaining a hierarchy of wealth or power in any way. But I would not have recognized that as an anarchistic society until relatively recently, mostly due to misinformation and propaganda against anarchy.

Anti-SJW

Alright, I'm guessing you're specifically on this page because you saw me upvote something on r/KotakuInAction or like a video from PSASitch or something like that. I'm not proud of this time period, where I read and watched a bit of Anti-SJW content. I'm glad to have moved on from this point of my life, and wish it hadn't happened in the first place. I don't really have any excuses, but appreciate understanding that I have grown as a person since this time.

I migrated a LOT of posts to this website for the sake of having them all in one place and under my control, rather than other websites'. I have not been able to look through the tens of thousands of posts (mostly upvotes/likes), but have done some basic filtering of these opinions I no longer hold. I'm open about the fact I once held these beliefs, but I don't need to be de facto promoting them by sharing them on this website. If you stumble across a post you think I'd rather not have on this site anymore, please reach out.

Radicalization

I believe a lot of things contributed to my radicalization, which happened sometime in the early 2020s. Ultimately I think I was just aware that I didn't really like the views I was being exposed to, the direction that media was trying to to pull me, and slowly over time just engaged less and less with that kind of content. I'd always been very economically leftist, so just needed to get over my edgy/cringe phase. I think what put the nail in the coffin was watching through the alt right playbook, a great series I highly recommend. I also started really enjoying a lot of leftist creators, like hasanabi, philosophy tube, and others. The people around me also affect my views, and after leaving college I think I interacted with nicer people on average. Of particular note here is my wife, who had their own political journey which has similarly culminated in us sort of having a positive feedback loop further and further left. Certain events like the BLM protests following George Floyd similarly cemented our position further and further left.

I actually want to also point out I've found a lot of people in this space to be very accepting of people who previously held problematic beliefs. It's largely why I feel comfortable (enough) having a lot of my history public both on this page and the site in general, and being able to describe how my political journey got me to where I am today, a very radical Leftist.

',12),b=JSON.parse('{"title":"My Political Journey","description":"","frontmatter":{"public":"true","slug":"my-political-journey","title":"My Political Journey","prev":false,"next":false},"headers":[],"relativePath":"garden/my-political-journey/index.md","filePath":"garden/my-political-journey/index.md"}'),u={name:"garden/my-political-journey/index.md"},v=Object.assign(u,{setup(p){const a=o();return(m,f)=>(l(),n("div",null,[h,e("p",null,[r("714 words, ~4 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),c]))}});export{b as __pageData,v as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as n,Q as e,K as r,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"My Political Journey",-1),d=["innerHTML"],c=s('
Referenced by:LeftismPolitical Quizzes

My Political Beliefs have changed over time, although I believe it mostly stems from me becoming increasingly informed. Since this website contains content from as far back as 2006, when I was only 10 years old, I'd like to make it extremely clear that I have changed as a person, as we all have, and disavow a lot of my older opinions, roughly everything before 2020 or so but to be safe let's just give a dynamic (current date - 2 years). It's likely you are on this page from viewing a timeline post from that range and clicking the banner. There are bits in that period I may still agree with, but perhaps it would be best to just assume I don't have a stance on it unless there's something more recent about it. Pages in the garden section of this site are evergreen though, meaning I'll keep them up to date as my views change. Feel completely free to judge me for my opinions in there.

Core beliefs

I believe I've been fairly political since I was quite young, and had a relatively consistent set of core values that have just been expressed in different ways and through different lenses during different points of my life. For example I've always believed in fairness, but have used that belief to both argue for and against affirmative action. Concepts like freedom or meritocracies have similarly been redefined as I've become more aware of the influence of imperialism and colonialism on our cultural values and society.

Other beliefs of mine have always been around, but I just wasn't informed enough to properly express my views. I've voiced for a very long time that I think society will inevitably trend towards post-scarcity, a world without class, currency, or jobs, where all our needs and desires are met fully, automatically, and sustainably. I've never once pictured that society retaining a hierarchy of wealth or power in any way. But I would not have recognized that as an anarchistic society until relatively recently, mostly due to misinformation and propaganda against anarchy.

Anti-SJW

Alright, I'm guessing you're specifically on this page because you saw me upvote something on r/KotakuInAction or like a video from PSASitch or something like that. I'm not proud of this time period, where I read and watched a bit of Anti-SJW content. I'm glad to have moved on from this point of my life, and wish it hadn't happened in the first place. I don't really have any excuses, but appreciate understanding that I have grown as a person since this time.

I migrated a LOT of posts to this website for the sake of having them all in one place and under my control, rather than other websites'. I have not been able to look through the tens of thousands of posts (mostly upvotes/likes), but have done some basic filtering of these opinions I no longer hold. I'm open about the fact I once held these beliefs, but I don't need to be de facto promoting them by sharing them on this website. If you stumble across a post you think I'd rather not have on this site anymore, please reach out.

Radicalization

I believe a lot of things contributed to my radicalization, which happened sometime in the early 2020s. Ultimately I think I was just aware that I didn't really like the views I was being exposed to, the direction that media was trying to to pull me, and slowly over time just engaged less and less with that kind of content. I'd always been very economically leftist, so just needed to get over my edgy/cringe phase. I think what put the nail in the coffin was watching through the alt right playbook, a great series I highly recommend. I also started really enjoying a lot of leftist creators, like hasanabi, philosophy tube, and others. The people around me also affect my views, and after leaving college I think I interacted with nicer people on average. Of particular note here is my wife, who had their own political journey which has similarly culminated in us sort of having a positive feedback loop further and further left. Certain events like the BLM protests following George Floyd similarly cemented our position further and further left.

I actually want to also point out I've found a lot of people in this space to be very accepting of people who previously held problematic beliefs. It's largely why I feel comfortable (enough) having a lot of my history public both on this page and the site in general, and being able to describe how my political journey got me to where I am today, a very radical Leftist.

',12),b=JSON.parse('{"title":"My Political Journey","description":"","frontmatter":{"public":"true","slug":"my-political-journey","title":"My Political Journey","prev":false,"next":false},"headers":[],"relativePath":"garden/my-political-journey/index.md","filePath":"garden/my-political-journey/index.md"}'),u={name:"garden/my-political-journey/index.md"},v=Object.assign(u,{setup(p){const a=o();return(m,f)=>(l(),n("div",null,[h,e("p",null,[r("714 words, ~4 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),c]))}});export{b as __pageData,v as default}; diff --git a/assets/garden_my-political-journey_index.md.D7DllfwU.lean.js b/assets/garden_my-political-journey_index.md.BXr8MFu7.lean.js similarity index 92% rename from assets/garden_my-political-journey_index.md.D7DllfwU.lean.js rename to assets/garden_my-political-journey_index.md.BXr8MFu7.lean.js index e317d09cb..bee01dbf2 100644 --- a/assets/garden_my-political-journey_index.md.D7DllfwU.lean.js +++ b/assets/garden_my-political-journey_index.md.BXr8MFu7.lean.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as n,Q as e,K as r,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"My Political Journey",-1),d=["innerHTML"],c=s("",12),b=JSON.parse('{"title":"My Political Journey","description":"","frontmatter":{"public":"true","slug":"my-political-journey","title":"My Political Journey","prev":false,"next":false},"headers":[],"relativePath":"garden/my-political-journey/index.md","filePath":"garden/my-political-journey/index.md"}'),u={name:"garden/my-political-journey/index.md"},v=Object.assign(u,{setup(p){const a=o();return(m,f)=>(l(),n("div",null,[h,e("p",null,[r("714 words, ~4 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),c]))}});export{b as __pageData,v as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as n,Q as e,K as r,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"My Political Journey",-1),d=["innerHTML"],c=s("",12),b=JSON.parse('{"title":"My Political Journey","description":"","frontmatter":{"public":"true","slug":"my-political-journey","title":"My Political Journey","prev":false,"next":false},"headers":[],"relativePath":"garden/my-political-journey/index.md","filePath":"garden/my-political-journey/index.md"}'),u={name:"garden/my-political-journey/index.md"},v=Object.assign(u,{setup(p){const a=o();return(m,f)=>(l(),n("div",null,[h,e("p",null,[r("714 words, ~4 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),c]))}});export{b as __pageData,v as default}; diff --git a/assets/garden_my-projects_index.md.DQ9IsS7b.js b/assets/garden_my-projects_index.md.wiE69CCE.js similarity index 97% rename from assets/garden_my-projects_index.md.DQ9IsS7b.js rename to assets/garden_my-projects_index.md.wiE69CCE.js index 95404c2cd..e1309845d 100644 --- a/assets/garden_my-projects_index.md.DQ9IsS7b.js +++ b/assets/garden_my-projects_index.md.wiE69CCE.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as t,q as d,Q as e,K as i,u as a,ag as l,p as o}from"./chunks/framework.Sr2_9k8k.js";const s=e("h1",{class:"p-name"},"My Projects",-1),h=["innerHTML"],c=l('
Referenced by:Guide to Incrementals/What is Content?
Tagged by:Advent IncrementalBabble BudsCapture the CitadelDice ArmorGame Dev TreeIncremental SocialKronosOpti-SpeechOrchardPlanar PioneersProfectusV-ecs

I like making games and tools!

Games

Tools (and other non-games)

',8),b=JSON.parse('{"title":"My Projects","description":"","frontmatter":{"index":"true","public":"true","slug":"my-projects","title":"My Projects","prev":false,"next":false},"headers":[],"relativePath":"garden/my-projects/index.md","filePath":"garden/my-projects/index.md"}'),m={name:"garden/my-projects/index.md"},x=Object.assign(m,{setup(p){const r=t();return(g,f)=>(o(),d("div",null,[s,e("p",null,[i("72 words, ~0 minute read. "),e("span",{innerHTML:a(n)[`site/${a(r).page.value.relativePath}`]},null,8,h)]),c]))}});export{b as __pageData,x as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as t,q as d,Q as e,K as i,u as a,ag as l,p as o}from"./chunks/framework.Sr2_9k8k.js";const s=e("h1",{class:"p-name"},"My Projects",-1),h=["innerHTML"],c=l('
Referenced by:Guide to Incrementals/What is Content?
Tagged by:Advent IncrementalBabble BudsCapture the CitadelDice ArmorGame Dev TreeIncremental SocialKronosOpti-SpeechOrchardPlanar PioneersProfectusV-ecs

I like making games and tools!

Games

Tools (and other non-games)

',8),b=JSON.parse('{"title":"My Projects","description":"","frontmatter":{"index":"true","public":"true","slug":"my-projects","title":"My Projects","prev":false,"next":false},"headers":[],"relativePath":"garden/my-projects/index.md","filePath":"garden/my-projects/index.md"}'),m={name:"garden/my-projects/index.md"},x=Object.assign(m,{setup(p){const r=t();return(g,f)=>(o(),d("div",null,[s,e("p",null,[i("72 words, ~0 minute read. "),e("span",{innerHTML:a(n)[`site/${a(r).page.value.relativePath}`]},null,8,h)]),c]))}});export{b as __pageData,x as default}; diff --git a/assets/garden_my-projects_index.md.DQ9IsS7b.lean.js b/assets/garden_my-projects_index.md.wiE69CCE.lean.js similarity index 91% rename from assets/garden_my-projects_index.md.DQ9IsS7b.lean.js rename to assets/garden_my-projects_index.md.wiE69CCE.lean.js index cf474e833..73a207186 100644 --- a/assets/garden_my-projects_index.md.DQ9IsS7b.lean.js +++ b/assets/garden_my-projects_index.md.wiE69CCE.lean.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as t,q as d,Q as e,K as i,u as a,ag as l,p as o}from"./chunks/framework.Sr2_9k8k.js";const s=e("h1",{class:"p-name"},"My Projects",-1),h=["innerHTML"],c=l("",8),b=JSON.parse('{"title":"My Projects","description":"","frontmatter":{"index":"true","public":"true","slug":"my-projects","title":"My Projects","prev":false,"next":false},"headers":[],"relativePath":"garden/my-projects/index.md","filePath":"garden/my-projects/index.md"}'),m={name:"garden/my-projects/index.md"},x=Object.assign(m,{setup(p){const r=t();return(g,f)=>(o(),d("div",null,[s,e("p",null,[i("72 words, ~0 minute read. "),e("span",{innerHTML:a(n)[`site/${a(r).page.value.relativePath}`]},null,8,h)]),c]))}});export{b as __pageData,x as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as t,q as d,Q as e,K as i,u as a,ag as l,p as o}from"./chunks/framework.Sr2_9k8k.js";const s=e("h1",{class:"p-name"},"My Projects",-1),h=["innerHTML"],c=l("",8),b=JSON.parse('{"title":"My Projects","description":"","frontmatter":{"index":"true","public":"true","slug":"my-projects","title":"My Projects","prev":false,"next":false},"headers":[],"relativePath":"garden/my-projects/index.md","filePath":"garden/my-projects/index.md"}'),m={name:"garden/my-projects/index.md"},x=Object.assign(m,{setup(p){const r=t();return(g,f)=>(o(),d("div",null,[s,e("p",null,[i("72 words, ~0 minute read. "),e("span",{innerHTML:a(n)[`site/${a(r).page.value.relativePath}`]},null,8,h)]),c]))}});export{b as __pageData,x as default}; diff --git a/assets/garden_neoliberalism_index.md.D3ylIaui.js b/assets/garden_neoliberalism_index.md.ui08wbfa.js similarity index 97% rename from assets/garden_neoliberalism_index.md.D3ylIaui.js rename to assets/garden_neoliberalism_index.md.ui08wbfa.js index 49f6338ee..1383454a0 100644 --- a/assets/garden_neoliberalism_index.md.D3ylIaui.js +++ b/assets/garden_neoliberalism_index.md.ui08wbfa.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as r,Q as e,K as s,u as a,ag as o,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Neoliberalism",-1),d=["innerHTML"],p=o('
Referenced by:IndividualismLocal CommunitiesTechnocracy

Neoliberalism is a conservative political philosophy that emphasizes Individualism and is resistant to change/progress. It became popular with the advent of President Raegan and his sweeping changes to the US economy and government (replacing the comparatively socialist polices of the New Deal and the Great Society), and affects both the Republican and Democratic US political parties.

I believe neoliberalism primarily affected the boomer generation and generation x. This lines up with trends in protest participation, which dipped during that time (by birth cohort) and picked back up starting with Millenials. The government is still largely controlled by those generations and still very neoliberal, despite increasingly progressive and left-leaning youth demographics.

Neoliberalism often supports ideas like meritocracies, calling them fair and just. However, by ignoring the context surrounding people's abilities and socioeconomic status, meritocracies end up merely reinforcing the current status quo - and if the current status quo is unfair or unjust, so too will be the meritocracy. Needless to say, we do not currently live in a society where the status quo is fair and just.

',5),b=JSON.parse('{"title":"Neoliberalism","description":"","frontmatter":{"alias":"Neoliberal","public":"true","slug":"neoliberalism","title":"Neoliberalism","prev":false,"next":false},"headers":[],"relativePath":"garden/neoliberalism/index.md","filePath":"garden/neoliberalism/index.md"}'),m={name:"garden/neoliberalism/index.md"},y=Object.assign(m,{setup(h){const i=n();return(u,g)=>(l(),r("div",null,[c,e("p",null,[s("133 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(i).page.value.relativePath}`]},null,8,d)]),p]))}});export{b as __pageData,y as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as r,Q as e,K as s,u as a,ag as o,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Neoliberalism",-1),d=["innerHTML"],p=o('
Referenced by:IndividualismLocal CommunitiesTechnocracy

Neoliberalism is a conservative political philosophy that emphasizes Individualism and is resistant to change/progress. It became popular with the advent of President Raegan and his sweeping changes to the US economy and government (replacing the comparatively socialist polices of the New Deal and the Great Society), and affects both the Republican and Democratic US political parties.

I believe neoliberalism primarily affected the boomer generation and generation x. This lines up with trends in protest participation, which dipped during that time (by birth cohort) and picked back up starting with Millenials. The government is still largely controlled by those generations and still very neoliberal, despite increasingly progressive and left-leaning youth demographics.

Neoliberalism often supports ideas like meritocracies, calling them fair and just. However, by ignoring the context surrounding people's abilities and socioeconomic status, meritocracies end up merely reinforcing the current status quo - and if the current status quo is unfair or unjust, so too will be the meritocracy. Needless to say, we do not currently live in a society where the status quo is fair and just.

',5),b=JSON.parse('{"title":"Neoliberalism","description":"","frontmatter":{"alias":"Neoliberal","public":"true","slug":"neoliberalism","title":"Neoliberalism","prev":false,"next":false},"headers":[],"relativePath":"garden/neoliberalism/index.md","filePath":"garden/neoliberalism/index.md"}'),m={name:"garden/neoliberalism/index.md"},y=Object.assign(m,{setup(h){const i=n();return(u,g)=>(l(),r("div",null,[c,e("p",null,[s("133 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(i).page.value.relativePath}`]},null,8,d)]),p]))}});export{b as __pageData,y as default}; diff --git a/assets/garden_neoliberalism_index.md.D3ylIaui.lean.js b/assets/garden_neoliberalism_index.md.ui08wbfa.lean.js similarity index 91% rename from assets/garden_neoliberalism_index.md.D3ylIaui.lean.js rename to assets/garden_neoliberalism_index.md.ui08wbfa.lean.js index f6fd13a68..988a43c49 100644 --- a/assets/garden_neoliberalism_index.md.D3ylIaui.lean.js +++ b/assets/garden_neoliberalism_index.md.ui08wbfa.lean.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as r,Q as e,K as s,u as a,ag as o,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Neoliberalism",-1),d=["innerHTML"],p=o("",5),b=JSON.parse('{"title":"Neoliberalism","description":"","frontmatter":{"alias":"Neoliberal","public":"true","slug":"neoliberalism","title":"Neoliberalism","prev":false,"next":false},"headers":[],"relativePath":"garden/neoliberalism/index.md","filePath":"garden/neoliberalism/index.md"}'),m={name:"garden/neoliberalism/index.md"},y=Object.assign(m,{setup(h){const i=n();return(u,g)=>(l(),r("div",null,[c,e("p",null,[s("133 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(i).page.value.relativePath}`]},null,8,d)]),p]))}});export{b as __pageData,y as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as r,Q as e,K as s,u as a,ag as o,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Neoliberalism",-1),d=["innerHTML"],p=o("",5),b=JSON.parse('{"title":"Neoliberalism","description":"","frontmatter":{"alias":"Neoliberal","public":"true","slug":"neoliberalism","title":"Neoliberalism","prev":false,"next":false},"headers":[],"relativePath":"garden/neoliberalism/index.md","filePath":"garden/neoliberalism/index.md"}'),m={name:"garden/neoliberalism/index.md"},y=Object.assign(m,{setup(h){const i=n();return(u,g)=>(l(),r("div",null,[c,e("p",null,[s("133 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(i).page.value.relativePath}`]},null,8,d)]),p]))}});export{b as __pageData,y as default}; diff --git a/assets/garden_network-of-knowledge_index.md.CRNiO9eP.js b/assets/garden_network-of-knowledge_index.md.CyD-TRX8.js similarity index 96% rename from assets/garden_network-of-knowledge_index.md.CRNiO9eP.js rename to assets/garden_network-of-knowledge_index.md.CyD-TRX8.js index 5aebed557..807412b59 100644 --- a/assets/garden_network-of-knowledge_index.md.CRNiO9eP.js +++ b/assets/garden_network-of-knowledge_index.md.CyD-TRX8.js @@ -1 +1 @@ -import{d as a}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as n,Q as e,K as s,u as t,ag as i,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Network of Knowledge",-1),c=["innerHTML"],u=i('
Referenced by:/nowOrchard

A theoretical concept for a federated protocol for people to write down their research, thoughts, etc. and link to other people's writings, such that it forms of network of all human thought

Existing Projects:

',5),k=JSON.parse('{"title":"Network of Knowledge","description":"","frontmatter":{"public":"true","slug":"network-of-knowledge","title":"Network of Knowledge","prev":false,"next":false},"headers":[],"relativePath":"garden/network-of-knowledge/index.md","filePath":"garden/network-of-knowledge/index.md"}'),h={name:"garden/network-of-knowledge/index.md"},m=Object.assign(h,{setup(f){const r=o();return(p,_)=>(l(),n("div",null,[d,e("p",null,[s("50 words, ~0 minute read. "),e("span",{innerHTML:t(a)[`site/${t(r).page.value.relativePath}`]},null,8,c)]),u]))}});export{k as __pageData,m as default}; +import{d as a}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as n,Q as e,K as s,u as t,ag as i,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Network of Knowledge",-1),c=["innerHTML"],u=i('
Referenced by:/nowOrchard

A theoretical concept for a federated protocol for people to write down their research, thoughts, etc. and link to other people's writings, such that it forms of network of all human thought

Existing Projects:

',5),k=JSON.parse('{"title":"Network of Knowledge","description":"","frontmatter":{"public":"true","slug":"network-of-knowledge","title":"Network of Knowledge","prev":false,"next":false},"headers":[],"relativePath":"garden/network-of-knowledge/index.md","filePath":"garden/network-of-knowledge/index.md"}'),h={name:"garden/network-of-knowledge/index.md"},m=Object.assign(h,{setup(f){const r=o();return(p,_)=>(l(),n("div",null,[d,e("p",null,[s("50 words, ~0 minute read. "),e("span",{innerHTML:t(a)[`site/${t(r).page.value.relativePath}`]},null,8,c)]),u]))}});export{k as __pageData,m as default}; diff --git a/assets/garden_network-of-knowledge_index.md.CRNiO9eP.lean.js b/assets/garden_network-of-knowledge_index.md.CyD-TRX8.lean.js similarity index 92% rename from assets/garden_network-of-knowledge_index.md.CRNiO9eP.lean.js rename to assets/garden_network-of-knowledge_index.md.CyD-TRX8.lean.js index ec4535b15..c4404aec1 100644 --- a/assets/garden_network-of-knowledge_index.md.CRNiO9eP.lean.js +++ b/assets/garden_network-of-knowledge_index.md.CyD-TRX8.lean.js @@ -1 +1 @@ -import{d as a}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as n,Q as e,K as s,u as t,ag as i,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Network of Knowledge",-1),c=["innerHTML"],u=i("",5),k=JSON.parse('{"title":"Network of Knowledge","description":"","frontmatter":{"public":"true","slug":"network-of-knowledge","title":"Network of Knowledge","prev":false,"next":false},"headers":[],"relativePath":"garden/network-of-knowledge/index.md","filePath":"garden/network-of-knowledge/index.md"}'),h={name:"garden/network-of-knowledge/index.md"},m=Object.assign(h,{setup(f){const r=o();return(p,_)=>(l(),n("div",null,[d,e("p",null,[s("50 words, ~0 minute read. "),e("span",{innerHTML:t(a)[`site/${t(r).page.value.relativePath}`]},null,8,c)]),u]))}});export{k as __pageData,m as default}; +import{d as a}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as n,Q as e,K as s,u as t,ag as i,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Network of Knowledge",-1),c=["innerHTML"],u=i("",5),k=JSON.parse('{"title":"Network of Knowledge","description":"","frontmatter":{"public":"true","slug":"network-of-knowledge","title":"Network of Knowledge","prev":false,"next":false},"headers":[],"relativePath":"garden/network-of-knowledge/index.md","filePath":"garden/network-of-knowledge/index.md"}'),h={name:"garden/network-of-knowledge/index.md"},m=Object.assign(h,{setup(f){const r=o();return(p,_)=>(l(),n("div",null,[d,e("p",null,[s("50 words, ~0 minute read. "),e("span",{innerHTML:t(a)[`site/${t(r).page.value.relativePath}`]},null,8,c)]),u]))}});export{k as __pageData,m as default}; diff --git a/assets/garden_no-politics-rules_index.md.CX084uTP.js b/assets/garden_no-politics-rules_index.md.CX084uTP.js deleted file mode 100644 index 7605f38bd..000000000 --- a/assets/garden_no-politics-rules_index.md.CX084uTP.js +++ /dev/null @@ -1 +0,0 @@ -import{d as a}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as n,Q as e,K as s,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},'\\"No Politics\\" Rules',-1),c=["innerHTML"],u=r('
Referenced by:Incremental SocialKronos

Communities - be they discord servers, forums, message boards, etc. - tend to have rules, and you'll likely see the same rules come up often. One of these common rules is the "no politics" rule. These rules may vary slightly in wording, but all share in being highly contentious. These are easily the rules most often broken and most often fought over - for and against.

Apolitical spaces' appeal

Apolitical spaces are very appealing to many people, hence the proliferation of "no politics" rules. These communities represent anything from safe spaces to escapism, depending on the person. These are genuinely useful and absolutely crucial for some peoples' mental well-being.

Apathy

Naturally, some section of the population truly does not care about politics and does not wish to be bothered by discussions about it. However, political apathy is implicit endorsement of the existing power structures and is typically unique to those who are already benefitting from those power structures. Privilege doesn't make you feel special, it makes the world feel "normal". Therefore, political apathy is not a good reason to create a "no politics" rule, and enacting such a rule under this pretense is very much a political act in and of itself.

Mental health

Some political topics are deeply personal and emotionally exhausting to engage with, even (or especially) the important ones. For example, trans rights are a critical political issue, but demanding that trans people engage in political discourse about their right to exist amounts to a form of re-traumatization. Personally, I think a "be kind" or "no attacking others" rule suffices here though.

I think moderation should be heavy handed when it comes to protecting community members. The intolerant do not deserve the benefit of the doubt.

If we extend unlimited tolerance even to those who are intolerant, if we are not prepared to defend a tolerant society against the onslaught of the intolerant, then the tolerant will be destroyed, and tolerance with them. - Karl Raimund Popper, The Open Society and Its Enemies

Debate is ineffective

Debate is not about solving the issues in society and is typically rhetorical sport that cares more about winning the conversation than building consensus. It has been shown to be ineffective at changing minds, and even more rarely for the right reasons (underlying philosophy rather than rhetorical performance). Honestly, this is a great justification for disallowing politics, although later on I'll add some nuance to this point so it doesn't stifle legitimately constructive conversation.

The issues with banning politics

Everything is Political. So what "no politics" really means is very subjective and likely to differ between different moderators, and will definitely differ from at least some community members. What this really amounts to is banning controversial ideas. As described in How to radicalize a normie, that means both statements like "Nazis are bad" and "Nazis are good" can be apolitical, as the community has a consensus that Nazis are bad and the second statement is probably just a joke. But once something is controversial it becomes political, so a statement like "feminism is good" would be disallowed. In practice, since the non-controversial stances typically mean upholding existing power structures (like capitalism, patriarchy, and white supremacy), you reach a situation where conversative or fascist viewpoints are allowed (despite the "probably just a joke" argument gets weaker and weaker) but progressive statements aren't.

To be clear, I'm not saying those who add "no politics" rules support those power structures.

Moderators may also introduce their own biases, so even if you don't believe the above arguments will hold true for your community. There will still likely be uneven enforcement of the no politics rule due to the subjective differences in what is and isn't political. This will mean the line is still drawn somewhere, and wherever that line is will be a political statement, it just might not be clear where it's drawn to the members and even moderators of the community, which will cause confusion and conflict.

Alternatives to "no politics" rules

Needless to say, all communities are different and there's no "one size fits all" solution. That said, I think every rule of this list should apply to any and all communities:

  • Be kind to each other. Intolerance is prohibited and will be met with decisive action.

And that's it! That's the one rule that should fully encapsulate all the forms of speech you don't want in your community, without upholding existing power structures like capitalism, patriarchy, or white supremacy. It's simple, and certainly not novel, but it's all you need. It's similarity to the golden rule should be noted, as essentially every culture in the world has arrived at essentially the same conclusion, that this rule is of the upmost importance.

Decisive action, in this context, should probably mean muting or banning. Intolerance is very important to keep out of the community. You do not owe the person your time and effort for rehabilitation, and your community does not need to risk their own members' safety giving the benefit of the doubt.

If, for the sake of clarity, you would like a longer version, you can use this:

Be kind to each other. Intolerance, harassment, and speech or behavior that marginalizes or dehumanizes others based on their identity (e.g., race, gender, sexual orientation, religion, or disability) are strictly prohibited. This includes both direct attacks and the promotion of ideologies or statements that threaten the dignity and safety of marginalized groups.

Sensitive topics

Alright, I have one bonus rule for you. Certain topics are definitely more likely to have induced trauma in community members in the past. It likely makes sense to have communities that are not explicitly about discussing those kinds of topics relegate them to their own channel, called sensitive-topics or serious-discussion, and update the rules to include something like this:

Discussions of potentially traumatic topics (e.g., violence, abuse, or discrimination) should be approached with care and sensitivity, and moderators may restrict or redirect such discussions if they risk causing harm to community members.

You'll note I don't mention punishments here, but just how the situation should be handled by moderators. This is in contrast to explicitly calling for decisive action against the intolerant. This is because punishments are not good deterrents, so the main goal in reacting to a transgression should be undoing the damage and preventing future harm, which can typically be done without needing to punish the transgressor.

Decentralized Moderation

This whole conversation should be contextualized as referring to discrete communities with designated moderators. That's not the only option though! I personally think social media should incorporate porous or continuous communities through Digital Locality, which by necessity would then have Decentralized Moderation that makes essentially everything you've read here no longer relevant. Oops.

',30),b=JSON.parse('{"title":"\\"No Politics\\" Rules","description":"","frontmatter":{"alias":"\\"No Politics\\" Rule","public":"true","slug":"-no-politics-rules","title":"\\"No Politics\\" Rules","prev":false,"next":false},"headers":[],"relativePath":"garden/no-politics-rules/index.md","filePath":"garden/no-politics-rules/index.md"}'),d={name:"garden/no-politics-rules/index.md"},v=Object.assign(d,{setup(p){const i=o();return(m,y)=>(l(),n("div",null,[h,e("p",null,[s("959 words, ~5 minute read. "),e("span",{innerHTML:t(a)[`site/${t(i).page.value.relativePath}`]},null,8,c)]),u]))}});export{b as __pageData,v as default}; diff --git a/assets/garden_no-politics-rules_index.md.CX084uTP.lean.js b/assets/garden_no-politics-rules_index.md.CX084uTP.lean.js deleted file mode 100644 index 1779d6b11..000000000 --- a/assets/garden_no-politics-rules_index.md.CX084uTP.lean.js +++ /dev/null @@ -1 +0,0 @@ -import{d as a}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as n,Q as e,K as s,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},'\\"No Politics\\" Rules',-1),c=["innerHTML"],u=r("",30),b=JSON.parse('{"title":"\\"No Politics\\" Rules","description":"","frontmatter":{"alias":"\\"No Politics\\" Rule","public":"true","slug":"-no-politics-rules","title":"\\"No Politics\\" Rules","prev":false,"next":false},"headers":[],"relativePath":"garden/no-politics-rules/index.md","filePath":"garden/no-politics-rules/index.md"}'),d={name:"garden/no-politics-rules/index.md"},v=Object.assign(d,{setup(p){const i=o();return(m,y)=>(l(),n("div",null,[h,e("p",null,[s("959 words, ~5 minute read. "),e("span",{innerHTML:t(a)[`site/${t(i).page.value.relativePath}`]},null,8,c)]),u]))}});export{b as __pageData,v as default}; diff --git a/assets/garden_no-politics-rules_index.md.C_dydAdq.js b/assets/garden_no-politics-rules_index.md.C_dydAdq.js new file mode 100644 index 000000000..8bb79ae30 --- /dev/null +++ b/assets/garden_no-politics-rules_index.md.C_dydAdq.js @@ -0,0 +1 @@ +import{d as o}from"./chunks/git.data.BcrWSzMU.js";import{M as a,q as n,Q as e,K as s,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},'"No Politics" Rules',-1),c=["innerHTML"],u=r('
Referenced by:Incremental SocialKronos

Communities - be they discord servers, forums, message boards, etc. - tend to have rules, and you'll likely see the same rules come up often. One of these common rules is the "no politics" rule. These rules may vary slightly in wording, but all share in being highly contentious. These are easily the rules most often broken and most often fought over - for and against.

Apolitical spaces' appeal

Apolitical spaces are very appealing to many people, hence the proliferation of "no politics" rules. These communities represent anything from safe spaces to escapism, depending on the person. These are genuinely useful and absolutely crucial for some peoples' mental well-being.

Apathy

Naturally, some section of the population truly does not care about politics and does not wish to be bothered by discussions about it. However, political apathy is implicit endorsement of the existing power structures and is typically unique to those who are already benefitting from those power structures. Privilege doesn't make you feel special, it makes the world feel "normal". Therefore, political apathy is not a good reason to create a "no politics" rule, and enacting such a rule under this pretense is very much a political act in and of itself.

Mental health

Some political topics are deeply personal and emotionally exhausting to engage with, even (or especially) the important ones. For example, trans rights are a critical political issue, but demanding that trans people engage in political discourse about their right to exist amounts to a form of re-traumatization. Personally, I think a "be kind" or "no attacking others" rule suffices here though.

I think moderation should be heavy handed when it comes to protecting community members. The intolerant do not deserve the benefit of the doubt.

If we extend unlimited tolerance even to those who are intolerant, if we are not prepared to defend a tolerant society against the onslaught of the intolerant, then the tolerant will be destroyed, and tolerance with them. - Karl Raimund Popper, The Open Society and Its Enemies

Debate is ineffective

Debate is not about solving the issues in society and is typically rhetorical sport that cares more about winning the conversation than building consensus. It has been shown to be ineffective at changing minds, and even more rarely for the right reasons (underlying philosophy rather than rhetorical performance). Honestly, this is a great justification for disallowing politics, although later on I'll add some nuance to this point so it doesn't stifle legitimately constructive conversation.

The issues with banning politics

Everything is Political. So what "no politics" really means is very subjective and likely to differ between different moderators, and will definitely differ from at least some community members. What this really amounts to is banning controversial ideas. As described in How to radicalize a normie, that means both statements like "Nazis are bad" and "Nazis are good" can be apolitical, as the community has a consensus that Nazis are bad and the second statement is probably just a joke. But once something is controversial it becomes political, so a statement like "feminism is good" would be disallowed. In practice, since the non-controversial stances typically mean upholding existing power structures (like capitalism, patriarchy, and white supremacy), you reach a situation where conversative or fascist viewpoints are allowed (despite the "probably just a joke" argument gets weaker and weaker) but progressive statements aren't.

To be clear, I'm not saying those who add "no politics" rules support those power structures.

Moderators may also introduce their own biases, so even if you don't believe the above arguments will hold true for your community. There will still likely be uneven enforcement of the no politics rule due to the subjective differences in what is and isn't political. This will mean the line is still drawn somewhere, and wherever that line is will be a political statement, it just might not be clear where it's drawn to the members and even moderators of the community, which will cause confusion and conflict.

Alternatives to "no politics" rules

Needless to say, all communities are different and there's no "one size fits all" solution. That said, I think every rule of this list should apply to any and all communities:

  1. Be kind to each other. Intolerance is prohibited and will be met with decisive action.

And that's it! That's the one rule that should fully encapsulate all the forms of speech you don't want in your community, without upholding existing power structures like capitalism, patriarchy, or white supremacy. It's simple, and certainly not novel, but it's all you need. It's similarity to the golden rule should be noted, as essentially every culture in the world has arrived at essentially the same conclusion, that this rule is of the upmost importance.

Decisive action, in this context, should probably mean muting or banning. Intolerance is very important to keep out of the community. You do not owe the person your time and effort for rehabilitation, and your community does not need to risk their own members' safety giving the benefit of the doubt.

If, for the sake of clarity, you would like a longer version, you can use this:

Be kind to each other. Intolerance, harassment, and speech or behavior that marginalizes or dehumanizes others based on their identity (e.g., race, gender, sexual orientation, religion, or disability) are strictly prohibited. This includes both direct attacks and the promotion of ideologies or statements that threaten the dignity and safety of marginalized groups.

Sensitive topics

Alright, I have one bonus rule for you. Certain topics are definitely more likely to have induced trauma in community members in the past. It likely makes sense to have communities that are not explicitly about discussing those kinds of topics relegate them to their own channel, called sensitive-topics or serious-discussion, and update the rules to include something like this:

Discussions of potentially traumatic topics (e.g., violence, abuse, or discrimination) should be approached with care and sensitivity, and moderators may restrict or redirect such discussions if they risk causing harm to community members.

You'll note I don't mention punishments here, but just how the situation should be handled by moderators. This is in contrast to explicitly calling for decisive action against the intolerant. This is because punishments are not good deterrents, so the main goal in reacting to a transgression should be undoing the damage and preventing future harm, which can typically be done without needing to punish the transgressor.

Decentralized Moderation

This whole conversation should be contextualized as referring to discrete communities with designated moderators. That's not the only option though! I personally think social media should incorporate porous or continuous communities through Digital Locality, which by necessity would then have Decentralized Moderation that makes essentially everything you've read here no longer relevant. Oops.

',30),b=JSON.parse('{"title":"\\"No Politics\\" Rules","description":"","frontmatter":{"alias":"\\"No Politics\\" Rule","public":"true","slug":"-no-politics-rules","title":"\\"No Politics\\" Rules","prev":false,"next":false},"headers":[],"relativePath":"garden/no-politics-rules/index.md","filePath":"garden/no-politics-rules/index.md"}'),d={name:"garden/no-politics-rules/index.md"},v=Object.assign(d,{setup(p){const i=a();return(m,y)=>(l(),n("div",null,[h,e("p",null,[s("960 words, ~5 minute read. "),e("span",{innerHTML:t(o)[`site/${t(i).page.value.relativePath}`]},null,8,c)]),u]))}});export{b as __pageData,v as default}; diff --git a/assets/garden_no-politics-rules_index.md.C_dydAdq.lean.js b/assets/garden_no-politics-rules_index.md.C_dydAdq.lean.js new file mode 100644 index 000000000..91e0bde20 --- /dev/null +++ b/assets/garden_no-politics-rules_index.md.C_dydAdq.lean.js @@ -0,0 +1 @@ +import{d as o}from"./chunks/git.data.BcrWSzMU.js";import{M as a,q as n,Q as e,K as s,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},'"No Politics" Rules',-1),c=["innerHTML"],u=r("",30),b=JSON.parse('{"title":"\\"No Politics\\" Rules","description":"","frontmatter":{"alias":"\\"No Politics\\" Rule","public":"true","slug":"-no-politics-rules","title":"\\"No Politics\\" Rules","prev":false,"next":false},"headers":[],"relativePath":"garden/no-politics-rules/index.md","filePath":"garden/no-politics-rules/index.md"}'),d={name:"garden/no-politics-rules/index.md"},v=Object.assign(d,{setup(p){const i=a();return(m,y)=>(l(),n("div",null,[h,e("p",null,[s("960 words, ~5 minute read. "),e("span",{innerHTML:t(o)[`site/${t(i).page.value.relativePath}`]},null,8,c)]),u]))}});export{b as __pageData,v as default}; diff --git a/assets/garden_nostr_index.md.DpzGkNqA.js b/assets/garden_nostr_index.md.CEXJKYHs.js similarity index 96% rename from assets/garden_nostr_index.md.DpzGkNqA.js rename to assets/garden_nostr_index.md.CEXJKYHs.js index 05e3e9877..2548d639f 100644 --- a/assets/garden_nostr_index.md.DpzGkNqA.js +++ b/assets/garden_nostr_index.md.CEXJKYHs.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as s,Q as e,K as i,u as a,ag as d,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Nostr",-1),c=["innerHTML"],p=d('
Referenced by:Decentralized Social Media
Tags:Decentralized

Nostr is the largest currently existing example of a fully Decentralized Social Media . It fixes the pick a server problem the Fediverse has with a properly Decentralized Identity .

Unfortunately, the network has a culture problem - its been primarily built by and caters to the cryptocurrency community and alt right. It'll be difficult to gain broad adoption as anyone using the platform will have to take care to explain how they're using nostr but aren't alt right.

',5),y=JSON.parse('{"title":"Nostr","description":"","frontmatter":{"public":"true","slug":"nostr","tags":["Decentralized"],"title":"Nostr","prev":false,"next":false},"headers":[],"relativePath":"garden/nostr/index.md","filePath":"garden/nostr/index.md"}'),m={name:"garden/nostr/index.md"},x=Object.assign(m,{setup(u){const t=n();return(h,_)=>(l(),s("div",null,[o,e("p",null,[i("52 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),p]))}});export{y as __pageData,x as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as s,Q as e,K as i,u as a,ag as d,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Nostr",-1),c=["innerHTML"],p=d('
Referenced by:Decentralized Social Media
Tags:Decentralized

Nostr is the largest currently existing example of a fully Decentralized Social Media . It fixes the pick a server problem the Fediverse has with a properly Decentralized Identity .

Unfortunately, the network has a culture problem - its been primarily built by and caters to the cryptocurrency community and alt right. It'll be difficult to gain broad adoption as anyone using the platform will have to take care to explain how they're using nostr but aren't alt right.

',5),y=JSON.parse('{"title":"Nostr","description":"","frontmatter":{"public":"true","slug":"nostr","tags":["Decentralized"],"title":"Nostr","prev":false,"next":false},"headers":[],"relativePath":"garden/nostr/index.md","filePath":"garden/nostr/index.md"}'),m={name:"garden/nostr/index.md"},x=Object.assign(m,{setup(u){const t=n();return(h,_)=>(l(),s("div",null,[o,e("p",null,[i("52 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),p]))}});export{y as __pageData,x as default}; diff --git a/assets/garden_nostr_index.md.DpzGkNqA.lean.js b/assets/garden_nostr_index.md.CEXJKYHs.lean.js similarity index 91% rename from assets/garden_nostr_index.md.DpzGkNqA.lean.js rename to assets/garden_nostr_index.md.CEXJKYHs.lean.js index c7c7039fa..8248f126f 100644 --- a/assets/garden_nostr_index.md.DpzGkNqA.lean.js +++ b/assets/garden_nostr_index.md.CEXJKYHs.lean.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as s,Q as e,K as i,u as a,ag as d,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Nostr",-1),c=["innerHTML"],p=d("",5),y=JSON.parse('{"title":"Nostr","description":"","frontmatter":{"public":"true","slug":"nostr","tags":["Decentralized"],"title":"Nostr","prev":false,"next":false},"headers":[],"relativePath":"garden/nostr/index.md","filePath":"garden/nostr/index.md"}'),m={name:"garden/nostr/index.md"},x=Object.assign(m,{setup(u){const t=n();return(h,_)=>(l(),s("div",null,[o,e("p",null,[i("52 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),p]))}});export{y as __pageData,x as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as s,Q as e,K as i,u as a,ag as d,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Nostr",-1),c=["innerHTML"],p=d("",5),y=JSON.parse('{"title":"Nostr","description":"","frontmatter":{"public":"true","slug":"nostr","tags":["Decentralized"],"title":"Nostr","prev":false,"next":false},"headers":[],"relativePath":"garden/nostr/index.md","filePath":"garden/nostr/index.md"}'),m={name:"garden/nostr/index.md"},x=Object.assign(m,{setup(u){const t=n();return(h,_)=>(l(),s("div",null,[o,e("p",null,[i("52 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),p]))}});export{y as __pageData,x as default}; diff --git a/assets/garden_objectivity_index.md.COU01MD8.js b/assets/garden_objectivity_index.md.DVnccZzk.js similarity index 99% rename from assets/garden_objectivity_index.md.COU01MD8.js rename to assets/garden_objectivity_index.md.DVnccZzk.js index 0fef9a632..0161e4c82 100644 --- a/assets/garden_objectivity_index.md.COU01MD8.js +++ b/assets/garden_objectivity_index.md.DVnccZzk.js @@ -1 +1 @@ -import{d as o}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as s,Q as e,K as n,u as t,ag as r,p as c}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Objectivity",-1),l=["innerHTML"],u=r('
Referenced by:Everything is PoliticalFilter BubblesScientific Constructivism

Objectivity is a myth. All we have are our subjective experiences, which are shaped by our environments and it's Social Constructs. Often something appearing objective more likely means its biased towards either your pre-conceived opinion, or the "status quo" opinion of the society or culture the work was created in.

When a social construct becomes sufficiently ingrained within society to the point it's not recognized as a construct, it can begin to be considered an "objective truth", which can lead to harmful results.

These social constructs form Echo Chambers around the entire society. In this way, echo chambers fractal within each other. That's not inherently a bad thing, but it's often difficult to recognize echo chambers from inside, and we're all ultimately inside at least one.

In practice, the idea that objectivity doesn't exist doesn't really impact anything. Our shared experiences are similar enough that our truths about most every day things are compatible. Where this most applies is when there's an argument between two people who are reaching different conclusions despite the same level of knowledge about the topic. In theory, you could probably find a shared common ground and determine that specific logical step in which you diverge. That divergence may be explained by our subjective perspectives on the world, mixed with our personal values. However, a side may claim their side of the divergence is the correct one due to some "objective truth". This is simply not so, but is all too often used to justify bigoted arguments.

Zoe Bee, in The Language War of Politics: How Metaphors Shape Our Thinking, discusses how reality is subjective and shaped by our experiences. This is framed by how metaphors take advantage of this concept to direct how we think about the tenor (the subject of the metaphor).

Economics

"Objective Economics" Isn't discusses how objectivity doesn't exist (at least in the context of economics), and how those who claim there is are doing so maliciously.

Yes, neoclassical/marginalist economics — and the Austrian economics to which Carroll predictably adheres — is technically “objective” in the sense that it’s a set of rules that objectively produce the same results from a given set of inputs every time. But the axioms of Austrian economics are, in themselves, trivially — or even circularly — true. What matters is the application of those axioms in a manner sufficiently sophisticated to generate meaningful statements about complex economic phenomena. The assumptions governing that application, and even what questions to ask, reflect value judgments. Any economic paradigm involves such choices, and the choices made will render it more relevant for some purposes and less relevant for others. Those choices are unavoidably political.

They discuss how claiming objectivity is used to add credibility to an argument. However, these "objective" arguments are only true within a specific framework of rules and restrictions, which they only suggest but don't prove matches reality. They effectively erase important context that are inconvenient for their politically motivated argument, and by doing so deliberately draw wrong conclusions.

"Dress is not an art project. It's a language, and you're babbling incoherently"

CJ the X discusses in How Jordan Peterson's Suits Taught Me Fashion how the idea that art is subjective hindered his ability to learn fashion as a teenager. He uses the above quote to articulate how contemporary values replacing the oppressive but comparatively well defined fashion values did him a disservice. He was essentially no longer able to learn and get advice on fashion other than through his own individual experimentation. He compares it to a language, where you can learn the grammar and vocabulary, but still be unable to make sensical sentences unless you understand the how and why people put these words together - like understanding the different articles of clothing, but not the why and how they get paired together. Arguing for fashion as a language, and that despite its subjectivity there's still necessarily a learned social component, enables people to be able to teach fashion without feeling like their just upholding old bigoted values. It's also a brilliant argument for why Social Constructs can be and are useful.

He also describes the history of fashion's values, and how previously there was the idea of a singular "objective" sense of fashion, and that those who disagree are just incorrect. Essentially that meant the goal of fashion was to look like how the elites look. He argues that today fashion is still trying to look how the elites look, but now the elites are fractured - academic elites have their own fashion from, say, the elites of hip hop. This actually sounds a lot like Butler's argument for Gender Performativity.

',14),y=JSON.parse('{"title":"Objectivity","description":"","frontmatter":{"public":"true","slug":"objectivity","title":"Objectivity","prev":false,"next":false},"headers":[],"relativePath":"garden/objectivity/index.md","filePath":"garden/objectivity/index.md"}'),d={name:"garden/objectivity/index.md"},v=Object.assign(d,{setup(p){const a=i();return(m,b)=>(c(),s("div",null,[h,e("p",null,[n("589 words, ~3 minute read. "),e("span",{innerHTML:t(o)[`site/${t(a).page.value.relativePath}`]},null,8,l)]),u]))}});export{y as __pageData,v as default}; +import{d as o}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as s,Q as e,K as n,u as t,ag as r,p as c}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Objectivity",-1),l=["innerHTML"],u=r('
Referenced by:Everything is PoliticalFilter BubblesScientific Constructivism

Objectivity is a myth. All we have are our subjective experiences, which are shaped by our environments and it's Social Constructs. Often something appearing objective more likely means its biased towards either your pre-conceived opinion, or the "status quo" opinion of the society or culture the work was created in.

When a social construct becomes sufficiently ingrained within society to the point it's not recognized as a construct, it can begin to be considered an "objective truth", which can lead to harmful results.

These social constructs form Echo Chambers around the entire society. In this way, echo chambers fractal within each other. That's not inherently a bad thing, but it's often difficult to recognize echo chambers from inside, and we're all ultimately inside at least one.

In practice, the idea that objectivity doesn't exist doesn't really impact anything. Our shared experiences are similar enough that our truths about most every day things are compatible. Where this most applies is when there's an argument between two people who are reaching different conclusions despite the same level of knowledge about the topic. In theory, you could probably find a shared common ground and determine that specific logical step in which you diverge. That divergence may be explained by our subjective perspectives on the world, mixed with our personal values. However, a side may claim their side of the divergence is the correct one due to some "objective truth". This is simply not so, but is all too often used to justify bigoted arguments.

Zoe Bee, in The Language War of Politics: How Metaphors Shape Our Thinking, discusses how reality is subjective and shaped by our experiences. This is framed by how metaphors take advantage of this concept to direct how we think about the tenor (the subject of the metaphor).

Economics

"Objective Economics" Isn't discusses how objectivity doesn't exist (at least in the context of economics), and how those who claim there is are doing so maliciously.

Yes, neoclassical/marginalist economics — and the Austrian economics to which Carroll predictably adheres — is technically “objective” in the sense that it’s a set of rules that objectively produce the same results from a given set of inputs every time. But the axioms of Austrian economics are, in themselves, trivially — or even circularly — true. What matters is the application of those axioms in a manner sufficiently sophisticated to generate meaningful statements about complex economic phenomena. The assumptions governing that application, and even what questions to ask, reflect value judgments. Any economic paradigm involves such choices, and the choices made will render it more relevant for some purposes and less relevant for others. Those choices are unavoidably political.

They discuss how claiming objectivity is used to add credibility to an argument. However, these "objective" arguments are only true within a specific framework of rules and restrictions, which they only suggest but don't prove matches reality. They effectively erase important context that are inconvenient for their politically motivated argument, and by doing so deliberately draw wrong conclusions.

"Dress is not an art project. It's a language, and you're babbling incoherently"

CJ the X discusses in How Jordan Peterson's Suits Taught Me Fashion how the idea that art is subjective hindered his ability to learn fashion as a teenager. He uses the above quote to articulate how contemporary values replacing the oppressive but comparatively well defined fashion values did him a disservice. He was essentially no longer able to learn and get advice on fashion other than through his own individual experimentation. He compares it to a language, where you can learn the grammar and vocabulary, but still be unable to make sensical sentences unless you understand the how and why people put these words together - like understanding the different articles of clothing, but not the why and how they get paired together. Arguing for fashion as a language, and that despite its subjectivity there's still necessarily a learned social component, enables people to be able to teach fashion without feeling like their just upholding old bigoted values. It's also a brilliant argument for why Social Constructs can be and are useful.

He also describes the history of fashion's values, and how previously there was the idea of a singular "objective" sense of fashion, and that those who disagree are just incorrect. Essentially that meant the goal of fashion was to look like how the elites look. He argues that today fashion is still trying to look how the elites look, but now the elites are fractured - academic elites have their own fashion from, say, the elites of hip hop. This actually sounds a lot like Butler's argument for Gender Performativity.

',14),y=JSON.parse('{"title":"Objectivity","description":"","frontmatter":{"public":"true","slug":"objectivity","title":"Objectivity","prev":false,"next":false},"headers":[],"relativePath":"garden/objectivity/index.md","filePath":"garden/objectivity/index.md"}'),d={name:"garden/objectivity/index.md"},v=Object.assign(d,{setup(p){const a=i();return(m,b)=>(c(),s("div",null,[h,e("p",null,[n("589 words, ~3 minute read. "),e("span",{innerHTML:t(o)[`site/${t(a).page.value.relativePath}`]},null,8,l)]),u]))}});export{y as __pageData,v as default}; diff --git a/assets/garden_objectivity_index.md.COU01MD8.lean.js b/assets/garden_objectivity_index.md.DVnccZzk.lean.js similarity index 91% rename from assets/garden_objectivity_index.md.COU01MD8.lean.js rename to assets/garden_objectivity_index.md.DVnccZzk.lean.js index c63bb13dc..f57c7be15 100644 --- a/assets/garden_objectivity_index.md.COU01MD8.lean.js +++ b/assets/garden_objectivity_index.md.DVnccZzk.lean.js @@ -1 +1 @@ -import{d as o}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as s,Q as e,K as n,u as t,ag as r,p as c}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Objectivity",-1),l=["innerHTML"],u=r("",14),y=JSON.parse('{"title":"Objectivity","description":"","frontmatter":{"public":"true","slug":"objectivity","title":"Objectivity","prev":false,"next":false},"headers":[],"relativePath":"garden/objectivity/index.md","filePath":"garden/objectivity/index.md"}'),d={name:"garden/objectivity/index.md"},v=Object.assign(d,{setup(p){const a=i();return(m,b)=>(c(),s("div",null,[h,e("p",null,[n("589 words, ~3 minute read. "),e("span",{innerHTML:t(o)[`site/${t(a).page.value.relativePath}`]},null,8,l)]),u]))}});export{y as __pageData,v as default}; +import{d as o}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as s,Q as e,K as n,u as t,ag as r,p as c}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Objectivity",-1),l=["innerHTML"],u=r("",14),y=JSON.parse('{"title":"Objectivity","description":"","frontmatter":{"public":"true","slug":"objectivity","title":"Objectivity","prev":false,"next":false},"headers":[],"relativePath":"garden/objectivity/index.md","filePath":"garden/objectivity/index.md"}'),d={name:"garden/objectivity/index.md"},v=Object.assign(d,{setup(p){const a=i();return(m,b)=>(c(),s("div",null,[h,e("p",null,[n("589 words, ~3 minute read. "),e("span",{innerHTML:t(o)[`site/${t(a).page.value.relativePath}`]},null,8,l)]),u]))}});export{y as __pageData,v as default}; diff --git a/assets/garden_open-source_index.md.6oyBcdDm.js b/assets/garden_open-source_index.md.Cacbphit.js similarity index 96% rename from assets/garden_open-source_index.md.6oyBcdDm.js rename to assets/garden_open-source_index.md.Cacbphit.js index 15a16896c..337254d3d 100644 --- a/assets/garden_open-source_index.md.6oyBcdDm.js +++ b/assets/garden_open-source_index.md.Cacbphit.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as d,q as t,Q as e,K as s,u as a,ag as i,p as o}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Open Source",-1),m=["innerHTML"],p=i('
Referenced by:Advent IncrementalCinnyCommuneDice ArmorForgejoGame Dev TreeLogseqMbinPlanar PioneersProfectusSynapseVitepressWeird

Projects with the source code publicly accessible

Typically also grants users the right to modify the code and redistribute those changes, depending on the license

',4),x=JSON.parse('{"title":"Open Source","description":"","frontmatter":{"public":"true","slug":"open-source","title":"Open Source","prev":false,"next":false},"headers":[],"relativePath":"garden/open-source/index.md","filePath":"garden/open-source/index.md"}'),l={name:"garden/open-source/index.md"},y=Object.assign(l,{setup(u){const n=d();return(g,h)=>(o(),t("div",null,[c,e("p",null,[s("25 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(n).page.value.relativePath}`]},null,8,m)]),p]))}});export{x as __pageData,y as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as d,q as t,Q as e,K as s,u as a,ag as i,p as o}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Open Source",-1),m=["innerHTML"],p=i('
Referenced by:Advent IncrementalCinnyCommuneDice ArmorForgejoGame Dev TreeLogseqMbinPlanar PioneersProfectusSynapseVitepressWeird

Projects with the source code publicly accessible

Typically also grants users the right to modify the code and redistribute those changes, depending on the license

',4),x=JSON.parse('{"title":"Open Source","description":"","frontmatter":{"public":"true","slug":"open-source","title":"Open Source","prev":false,"next":false},"headers":[],"relativePath":"garden/open-source/index.md","filePath":"garden/open-source/index.md"}'),l={name:"garden/open-source/index.md"},y=Object.assign(l,{setup(u){const n=d();return(g,h)=>(o(),t("div",null,[c,e("p",null,[s("25 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(n).page.value.relativePath}`]},null,8,m)]),p]))}});export{x as __pageData,y as default}; diff --git a/assets/garden_open-source_index.md.6oyBcdDm.lean.js b/assets/garden_open-source_index.md.Cacbphit.lean.js similarity index 91% rename from assets/garden_open-source_index.md.6oyBcdDm.lean.js rename to assets/garden_open-source_index.md.Cacbphit.lean.js index 6f4533a2c..f534e20e8 100644 --- a/assets/garden_open-source_index.md.6oyBcdDm.lean.js +++ b/assets/garden_open-source_index.md.Cacbphit.lean.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as d,q as t,Q as e,K as s,u as a,ag as i,p as o}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Open Source",-1),m=["innerHTML"],p=i("",4),x=JSON.parse('{"title":"Open Source","description":"","frontmatter":{"public":"true","slug":"open-source","title":"Open Source","prev":false,"next":false},"headers":[],"relativePath":"garden/open-source/index.md","filePath":"garden/open-source/index.md"}'),l={name:"garden/open-source/index.md"},y=Object.assign(l,{setup(u){const n=d();return(g,h)=>(o(),t("div",null,[c,e("p",null,[s("25 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(n).page.value.relativePath}`]},null,8,m)]),p]))}});export{x as __pageData,y as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as d,q as t,Q as e,K as s,u as a,ag as i,p as o}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Open Source",-1),m=["innerHTML"],p=i("",4),x=JSON.parse('{"title":"Open Source","description":"","frontmatter":{"public":"true","slug":"open-source","title":"Open Source","prev":false,"next":false},"headers":[],"relativePath":"garden/open-source/index.md","filePath":"garden/open-source/index.md"}'),l={name:"garden/open-source/index.md"},y=Object.assign(l,{setup(u){const n=d();return(g,h)=>(o(),t("div",null,[c,e("p",null,[s("25 words, ~0 minute read. "),e("span",{innerHTML:a(r)[`site/${a(n).page.value.relativePath}`]},null,8,m)]),p]))}});export{x as __pageData,y as default}; diff --git a/assets/garden_opti-speech_index.md.Dp0ll6kT.js b/assets/garden_opti-speech_index.md.f2BVQmXm.js similarity index 98% rename from assets/garden_opti-speech_index.md.Dp0ll6kT.js rename to assets/garden_opti-speech_index.md.f2BVQmXm.js index 83365b561..7734828a4 100644 --- a/assets/garden_opti-speech_index.md.Dp0ll6kT.js +++ b/assets/garden_opti-speech_index.md.f2BVQmXm.js @@ -1 +1 @@ -import{M as r,q as s,Q as e,K as n,u as t,ag as a,p as o,av as l,aw as c,ax as p,ay as d}from"./chunks/framework.Sr2_9k8k.js";import{d as h}from"./chunks/git.data.D-Ga3RhB.js";const m=e("h1",{class:"p-name"},"Opti-Speech",-1),g=["innerHTML"],u=a('
Tags:My Projects

In college I continued development on the Opti-Speech project, originally built alongside the scientific paper Opti-speech: a real-time, 3d visual feedback system for speech training

The Original Project

The Optispeech project involves designing and testing a real-time tongue model that can be viewed in a transparent head while a subject talks — for the purposes of treating speech errors and teaching foreign language sounds. This work has been conducted in partnership with Vulintus and with support from the National Institutes of Health (NIH).

',6),_=e("iframe",{width:"560",height:"315",src:"https://www.youtube.com/embed/9uHqIRs7ZjM",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:"",style:{display:"block",margin:"auto"}},null,-1),f=e("p",null,"This video shows a talker with WAVE sensors placed on the tongue hitting a virtual target sphere located at the alveolar ridge. When an alveolar consonant is hit (e.g., /s/, /n/, /d/) the sphere changes color from red to green.",-1),v=e("iframe",{width:"560",height:"315",src:"https://www.youtube.com/embed/Oz42mKvlzqI",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:"",style:{display:"block",margin:"auto"}},null,-1),y=a('

This video shows an American talker learning a novel sound not found in English. When the post-alveolar consonant is hit, the target sphere changes color from red to green. Here, the NDI WAVE system serves as input.

My Work

As the sole programmer at UT Dallas Speech Production Lab at the time, my changes involved updating to a more modern version of Unity, improving the interface, in general cleaning up tech debt so it can more easily support new features, and added support for additional EMA systems, namely the Carstens AG501.

In addition, the program now includes documentation and unit tests to improve program stability and maintainability going forward.

',7),O=JSON.parse('{"title":"Opti-Speech","description":"","frontmatter":{"public":"true","slug":"opti-speech","tags":["My Projects"],"title":"Opti-Speech","prev":false,"next":false},"headers":[],"relativePath":"garden/opti-speech/index.md","filePath":"garden/opti-speech/index.md"}'),w={name:"garden/opti-speech/index.md"},S=Object.assign(w,{setup(b){const i=r();return(T,k)=>(o(),s("div",null,[m,e("p",null,[n("312 words, ~2 minute read. "),e("span",{innerHTML:t(h)[`site/${t(i).page.value.relativePath}`]},null,8,g)]),u,_,f,v,y]))}});export{O as __pageData,S as default}; +import{M as r,q as s,Q as e,K as n,u as t,ag as a,p as o,av as l,aw as c,ax as p,ay as d}from"./chunks/framework.Sr2_9k8k.js";import{d as h}from"./chunks/git.data.BcrWSzMU.js";const m=e("h1",{class:"p-name"},"Opti-Speech",-1),g=["innerHTML"],u=a('
Tags:My Projects

In college I continued development on the Opti-Speech project, originally built alongside the scientific paper Opti-speech: a real-time, 3d visual feedback system for speech training

The Original Project

The Optispeech project involves designing and testing a real-time tongue model that can be viewed in a transparent head while a subject talks — for the purposes of treating speech errors and teaching foreign language sounds. This work has been conducted in partnership with Vulintus and with support from the National Institutes of Health (NIH).

',6),_=e("iframe",{width:"560",height:"315",src:"https://www.youtube.com/embed/9uHqIRs7ZjM",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:"",style:{display:"block",margin:"auto"}},null,-1),f=e("p",null,"This video shows a talker with WAVE sensors placed on the tongue hitting a virtual target sphere located at the alveolar ridge. When an alveolar consonant is hit (e.g., /s/, /n/, /d/) the sphere changes color from red to green.",-1),v=e("iframe",{width:"560",height:"315",src:"https://www.youtube.com/embed/Oz42mKvlzqI",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:"",style:{display:"block",margin:"auto"}},null,-1),y=a('

This video shows an American talker learning a novel sound not found in English. When the post-alveolar consonant is hit, the target sphere changes color from red to green. Here, the NDI WAVE system serves as input.

My Work

As the sole programmer at UT Dallas Speech Production Lab at the time, my changes involved updating to a more modern version of Unity, improving the interface, in general cleaning up tech debt so it can more easily support new features, and added support for additional EMA systems, namely the Carstens AG501.

In addition, the program now includes documentation and unit tests to improve program stability and maintainability going forward.

',7),O=JSON.parse('{"title":"Opti-Speech","description":"","frontmatter":{"public":"true","slug":"opti-speech","tags":["My Projects"],"title":"Opti-Speech","prev":false,"next":false},"headers":[],"relativePath":"garden/opti-speech/index.md","filePath":"garden/opti-speech/index.md"}'),w={name:"garden/opti-speech/index.md"},S=Object.assign(w,{setup(b){const i=r();return(T,k)=>(o(),s("div",null,[m,e("p",null,[n("312 words, ~2 minute read. "),e("span",{innerHTML:t(h)[`site/${t(i).page.value.relativePath}`]},null,8,g)]),u,_,f,v,y]))}});export{O as __pageData,S as default}; diff --git a/assets/garden_opti-speech_index.md.Dp0ll6kT.lean.js b/assets/garden_opti-speech_index.md.f2BVQmXm.lean.js similarity index 96% rename from assets/garden_opti-speech_index.md.Dp0ll6kT.lean.js rename to assets/garden_opti-speech_index.md.f2BVQmXm.lean.js index 329a0a87e..85ebcc05f 100644 --- a/assets/garden_opti-speech_index.md.Dp0ll6kT.lean.js +++ b/assets/garden_opti-speech_index.md.f2BVQmXm.lean.js @@ -1 +1 @@ -import{M as r,q as s,Q as e,K as n,u as t,ag as a,p as o,av as l,aw as c,ax as p,ay as d}from"./chunks/framework.Sr2_9k8k.js";import{d as h}from"./chunks/git.data.D-Ga3RhB.js";const m=e("h1",{class:"p-name"},"Opti-Speech",-1),g=["innerHTML"],u=a("",6),_=e("iframe",{width:"560",height:"315",src:"https://www.youtube.com/embed/9uHqIRs7ZjM",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:"",style:{display:"block",margin:"auto"}},null,-1),f=e("p",null,"This video shows a talker with WAVE sensors placed on the tongue hitting a virtual target sphere located at the alveolar ridge. When an alveolar consonant is hit (e.g., /s/, /n/, /d/) the sphere changes color from red to green.",-1),v=e("iframe",{width:"560",height:"315",src:"https://www.youtube.com/embed/Oz42mKvlzqI",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:"",style:{display:"block",margin:"auto"}},null,-1),y=a("",7),O=JSON.parse('{"title":"Opti-Speech","description":"","frontmatter":{"public":"true","slug":"opti-speech","tags":["My Projects"],"title":"Opti-Speech","prev":false,"next":false},"headers":[],"relativePath":"garden/opti-speech/index.md","filePath":"garden/opti-speech/index.md"}'),w={name:"garden/opti-speech/index.md"},S=Object.assign(w,{setup(b){const i=r();return(T,k)=>(o(),s("div",null,[m,e("p",null,[n("312 words, ~2 minute read. "),e("span",{innerHTML:t(h)[`site/${t(i).page.value.relativePath}`]},null,8,g)]),u,_,f,v,y]))}});export{O as __pageData,S as default}; +import{M as r,q as s,Q as e,K as n,u as t,ag as a,p as o,av as l,aw as c,ax as p,ay as d}from"./chunks/framework.Sr2_9k8k.js";import{d as h}from"./chunks/git.data.BcrWSzMU.js";const m=e("h1",{class:"p-name"},"Opti-Speech",-1),g=["innerHTML"],u=a("",6),_=e("iframe",{width:"560",height:"315",src:"https://www.youtube.com/embed/9uHqIRs7ZjM",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:"",style:{display:"block",margin:"auto"}},null,-1),f=e("p",null,"This video shows a talker with WAVE sensors placed on the tongue hitting a virtual target sphere located at the alveolar ridge. When an alveolar consonant is hit (e.g., /s/, /n/, /d/) the sphere changes color from red to green.",-1),v=e("iframe",{width:"560",height:"315",src:"https://www.youtube.com/embed/Oz42mKvlzqI",frameborder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowfullscreen:"",style:{display:"block",margin:"auto"}},null,-1),y=a("",7),O=JSON.parse('{"title":"Opti-Speech","description":"","frontmatter":{"public":"true","slug":"opti-speech","tags":["My Projects"],"title":"Opti-Speech","prev":false,"next":false},"headers":[],"relativePath":"garden/opti-speech/index.md","filePath":"garden/opti-speech/index.md"}'),w={name:"garden/opti-speech/index.md"},S=Object.assign(w,{setup(b){const i=r();return(T,k)=>(o(),s("div",null,[m,e("p",null,[n("312 words, ~2 minute read. "),e("span",{innerHTML:t(h)[`site/${t(i).page.value.relativePath}`]},null,8,g)]),u,_,f,v,y]))}});export{O as __pageData,S as default}; diff --git a/assets/garden_orchard_index.md.BJ1pQXIs.js b/assets/garden_orchard_index.md.D91PKd0A.js similarity index 98% rename from assets/garden_orchard_index.md.BJ1pQXIs.js rename to assets/garden_orchard_index.md.D91PKd0A.js index b7a0bd491..cbac275aa 100644 --- a/assets/garden_orchard_index.md.BJ1pQXIs.js +++ b/assets/garden_orchard_index.md.D91PKd0A.js @@ -1 +1 @@ -import{d as o}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as s,Q as e,K as r,u as a,ag as i,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Orchard",-1),h=["innerHTML"],d=i('
Referenced by:/now
Tags:My Projects

This is an app I'm designing and at least building a mock for. I'd like it to either get built directly into Commune or integrate with it. The purpose of the app is to organize and grow a Network of Knowledge (or Digital Garden) sorted by topic. It achieves this through a concept called message gardening, the process of converting casual conversations into formal, referenceable stores of knowledge.

The problem I have that I'm trying to solve is having a lot of conversations about various topics stretching back far into the past and across many platforms. I often want to review something I said on a given topic and find it difficult to do so. This app would make it far easier to retrieve my notes on any topic. It's different than a traditional note-taking app because it works with conversations directly, which is how my "notes" on a topic initially start out as. As a secondary effect, this will also fix some of the issues described in the chat glue comic. I'd like it to eventually support even more of the ideas proposed in that comment, like replies and reactions to parts of a message.

The main way you interact with the app is by conversing. As you converse in your group chats and DMs, which are technically through matrix but can bridge to other platforms like discord, you can specify topic changes. These will break the conversation up into pieces, and each piece gets added to each of the topics it was about (with links to the convo from before and after that one). If a piece was about multiple topics it forms a link between those topics and considers them in some way related. These links are represented as lines in the topics graph, and cause the topics to be physically closer within the graph. Topics can use slashes to indicate hierarchy, which will also place them next to each other in the graph.

Non-conversation notes

In addition to including conversations, I want to support freeform notes that also discuss one or more topics. Through leaf's compositional structure, in theory any entity should be able to be added to the network.

Another type of non-conversation note could be excerpts from online articles, which could be automatically cited.

When allowing these kinds of notes, users should be encouraged to split notes as small as possible. This allows us to avoid needing something like Garden-RSS by just showing that a note has updated, and showing the new content.

Communal Networks

By integrating with commune on the server side, the network could be maintained by the entire community, allowing any (trusted) members to mark topic changes. This has the benefit of making maintenance easier on any individual, but also it means users wanting to catch up on the conversations can now do so via the graph, ignoring any conversations that don't mention any topics that user doesn't particularly care about.

Federation

Allow clients to "follow" those communal networks, replicating them locally and merging them together (aliasing similar topics as necessary). This allows users to get very large networks much more easily, and further incentivizes contributing to the communal networks.

LLMs

A local LLM could assist in marking topic changes automatically, allowing you to get the benefits of the conversation being broken up for catching up even while on a non-commune chat.

LLMs could also be given the topics as context and be able to query the network for knowledge.

Tech Stack

The client will be a matrix client that stores all the messages locally. It'll use Fedi v2 to store the messages and other data, making the whole app Local-First Software. The rest of the app will be a web-based UI, using Neutralino.js or an alternative.

Actually, tauri apparently doesn't require rust per-say, and has things like mobile support and a better dev experience.

The server will be something that ensures commune servers can share topic changes across the community.

Consider using Animata components

',22),b=JSON.parse('{"title":"Orchard","description":"","frontmatter":{"public":"true","slug":"orchard","tags":["My Projects"],"title":"Orchard","prev":false,"next":false},"headers":[],"relativePath":"garden/orchard/index.md","filePath":"garden/orchard/index.md"}'),p={name:"garden/orchard/index.md"},y=Object.assign(p,{setup(u){const t=n();return(m,g)=>(l(),s("div",null,[c,e("p",null,[r("634 words, ~3 minute read. "),e("span",{innerHTML:a(o)[`site/${a(t).page.value.relativePath}`]},null,8,h)]),d]))}});export{b as __pageData,y as default}; +import{d as o}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as s,Q as e,K as r,u as a,ag as i,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Orchard",-1),h=["innerHTML"],d=i('
Referenced by:/now
Tags:My Projects

This is an app I'm designing and at least building a mock for. I'd like it to either get built directly into Commune or integrate with it. The purpose of the app is to organize and grow a Network of Knowledge (or Digital Garden) sorted by topic. It achieves this through a concept called message gardening, the process of converting casual conversations into formal, referenceable stores of knowledge.

The problem I have that I'm trying to solve is having a lot of conversations about various topics stretching back far into the past and across many platforms. I often want to review something I said on a given topic and find it difficult to do so. This app would make it far easier to retrieve my notes on any topic. It's different than a traditional note-taking app because it works with conversations directly, which is how my "notes" on a topic initially start out as. As a secondary effect, this will also fix some of the issues described in the chat glue comic. I'd like it to eventually support even more of the ideas proposed in that comment, like replies and reactions to parts of a message.

The main way you interact with the app is by conversing. As you converse in your group chats and DMs, which are technically through matrix but can bridge to other platforms like discord, you can specify topic changes. These will break the conversation up into pieces, and each piece gets added to each of the topics it was about (with links to the convo from before and after that one). If a piece was about multiple topics it forms a link between those topics and considers them in some way related. These links are represented as lines in the topics graph, and cause the topics to be physically closer within the graph. Topics can use slashes to indicate hierarchy, which will also place them next to each other in the graph.

Non-conversation notes

In addition to including conversations, I want to support freeform notes that also discuss one or more topics. Through leaf's compositional structure, in theory any entity should be able to be added to the network.

Another type of non-conversation note could be excerpts from online articles, which could be automatically cited.

When allowing these kinds of notes, users should be encouraged to split notes as small as possible. This allows us to avoid needing something like Garden-RSS by just showing that a note has updated, and showing the new content.

Communal Networks

By integrating with commune on the server side, the network could be maintained by the entire community, allowing any (trusted) members to mark topic changes. This has the benefit of making maintenance easier on any individual, but also it means users wanting to catch up on the conversations can now do so via the graph, ignoring any conversations that don't mention any topics that user doesn't particularly care about.

Federation

Allow clients to "follow" those communal networks, replicating them locally and merging them together (aliasing similar topics as necessary). This allows users to get very large networks much more easily, and further incentivizes contributing to the communal networks.

LLMs

A local LLM could assist in marking topic changes automatically, allowing you to get the benefits of the conversation being broken up for catching up even while on a non-commune chat.

LLMs could also be given the topics as context and be able to query the network for knowledge.

Tech Stack

The client will be a matrix client that stores all the messages locally. It'll use Fedi v2 to store the messages and other data, making the whole app Local-First Software. The rest of the app will be a web-based UI, using Neutralino.js or an alternative.

Actually, tauri apparently doesn't require rust per-say, and has things like mobile support and a better dev experience.

The server will be something that ensures commune servers can share topic changes across the community.

Consider using Animata components

',22),b=JSON.parse('{"title":"Orchard","description":"","frontmatter":{"public":"true","slug":"orchard","tags":["My Projects"],"title":"Orchard","prev":false,"next":false},"headers":[],"relativePath":"garden/orchard/index.md","filePath":"garden/orchard/index.md"}'),p={name:"garden/orchard/index.md"},y=Object.assign(p,{setup(u){const t=n();return(m,g)=>(l(),s("div",null,[c,e("p",null,[r("634 words, ~3 minute read. "),e("span",{innerHTML:a(o)[`site/${a(t).page.value.relativePath}`]},null,8,h)]),d]))}});export{b as __pageData,y as default}; diff --git a/assets/garden_orchard_index.md.BJ1pQXIs.lean.js b/assets/garden_orchard_index.md.D91PKd0A.lean.js similarity index 91% rename from assets/garden_orchard_index.md.BJ1pQXIs.lean.js rename to assets/garden_orchard_index.md.D91PKd0A.lean.js index 888880eb4..41fbec0b4 100644 --- a/assets/garden_orchard_index.md.BJ1pQXIs.lean.js +++ b/assets/garden_orchard_index.md.D91PKd0A.lean.js @@ -1 +1 @@ -import{d as o}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as s,Q as e,K as r,u as a,ag as i,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Orchard",-1),h=["innerHTML"],d=i("",22),b=JSON.parse('{"title":"Orchard","description":"","frontmatter":{"public":"true","slug":"orchard","tags":["My Projects"],"title":"Orchard","prev":false,"next":false},"headers":[],"relativePath":"garden/orchard/index.md","filePath":"garden/orchard/index.md"}'),p={name:"garden/orchard/index.md"},y=Object.assign(p,{setup(u){const t=n();return(m,g)=>(l(),s("div",null,[c,e("p",null,[r("634 words, ~3 minute read. "),e("span",{innerHTML:a(o)[`site/${a(t).page.value.relativePath}`]},null,8,h)]),d]))}});export{b as __pageData,y as default}; +import{d as o}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as s,Q as e,K as r,u as a,ag as i,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Orchard",-1),h=["innerHTML"],d=i("",22),b=JSON.parse('{"title":"Orchard","description":"","frontmatter":{"public":"true","slug":"orchard","tags":["My Projects"],"title":"Orchard","prev":false,"next":false},"headers":[],"relativePath":"garden/orchard/index.md","filePath":"garden/orchard/index.md"}'),p={name:"garden/orchard/index.md"},y=Object.assign(p,{setup(u){const t=n();return(m,g)=>(l(),s("div",null,[c,e("p",null,[r("634 words, ~3 minute read. "),e("span",{innerHTML:a(o)[`site/${a(t).page.value.relativePath}`]},null,8,h)]),d]))}});export{b as __pageData,y as default}; diff --git a/assets/garden_personality_index.md.ChhNeN5J.js b/assets/garden_personality_index.md.ClTZlrBX.js similarity index 96% rename from assets/garden_personality_index.md.ChhNeN5J.js rename to assets/garden_personality_index.md.ClTZlrBX.js index c54234997..3cf54e823 100644 --- a/assets/garden_personality_index.md.ChhNeN5J.js +++ b/assets/garden_personality_index.md.ClTZlrBX.js @@ -1 +1 @@ -import{d as a}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as n,Q as e,K as s,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const p=e("h1",{class:"p-name"},"Personality",-1),d=["innerHTML"],h=r('

I think personality is best explained with a combination of Social Identity Theory and Self Categorization Theory

  • Social Identity Theory
    • Posits that significant amount of our personality is derived from our membership in various social groups
    • People categorize themselves and others into groups based on nationality, gender, profession, interests, etc.
    • The groups one feels they most identity with end up shaping one's behaviors
    • Also leads to discrimination and out-group homogeneity
  • Self Categorization Theory
    • People act in ways that they perceive as typical for the members of the group they identify with
    • Can lead to viewing oneself as an embodiment of the group prototype rather than a unique individual
  • I believe people adopt core identities and then subconsciously use their perception of how people with those identities as a mnemonic for how they should behave
  • Gender Performativity maps cleanly onto these theories
',3),g=JSON.parse('{"title":"Personality","description":"","frontmatter":{"public":"true","slug":"personality","title":"Personality","prev":false,"next":false},"headers":[],"relativePath":"garden/personality/index.md","filePath":"garden/personality/index.md"}'),u={name:"garden/personality/index.md"},v=Object.assign(u,{setup(c){const i=o();return(m,y)=>(l(),n("div",null,[p,e("p",null,[s("143 words, ~1 minute read. "),e("span",{innerHTML:t(a)[`site/${t(i).page.value.relativePath}`]},null,8,d)]),h]))}});export{g as __pageData,v as default}; +import{d as a}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as n,Q as e,K as s,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const p=e("h1",{class:"p-name"},"Personality",-1),d=["innerHTML"],h=r('

I think personality is best explained with a combination of Social Identity Theory and Self Categorization Theory

  • Social Identity Theory
    • Posits that significant amount of our personality is derived from our membership in various social groups
    • People categorize themselves and others into groups based on nationality, gender, profession, interests, etc.
    • The groups one feels they most identity with end up shaping one's behaviors
    • Also leads to discrimination and out-group homogeneity
  • Self Categorization Theory
    • People act in ways that they perceive as typical for the members of the group they identify with
    • Can lead to viewing oneself as an embodiment of the group prototype rather than a unique individual
  • I believe people adopt core identities and then subconsciously use their perception of how people with those identities as a mnemonic for how they should behave
  • Gender Performativity maps cleanly onto these theories
',3),g=JSON.parse('{"title":"Personality","description":"","frontmatter":{"public":"true","slug":"personality","title":"Personality","prev":false,"next":false},"headers":[],"relativePath":"garden/personality/index.md","filePath":"garden/personality/index.md"}'),u={name:"garden/personality/index.md"},v=Object.assign(u,{setup(c){const i=o();return(m,y)=>(l(),n("div",null,[p,e("p",null,[s("143 words, ~1 minute read. "),e("span",{innerHTML:t(a)[`site/${t(i).page.value.relativePath}`]},null,8,d)]),h]))}});export{g as __pageData,v as default}; diff --git a/assets/garden_personality_index.md.ChhNeN5J.lean.js b/assets/garden_personality_index.md.ClTZlrBX.lean.js similarity index 91% rename from assets/garden_personality_index.md.ChhNeN5J.lean.js rename to assets/garden_personality_index.md.ClTZlrBX.lean.js index 08c000bb6..b55bd7d55 100644 --- a/assets/garden_personality_index.md.ChhNeN5J.lean.js +++ b/assets/garden_personality_index.md.ClTZlrBX.lean.js @@ -1 +1 @@ -import{d as a}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as n,Q as e,K as s,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const p=e("h1",{class:"p-name"},"Personality",-1),d=["innerHTML"],h=r("",3),g=JSON.parse('{"title":"Personality","description":"","frontmatter":{"public":"true","slug":"personality","title":"Personality","prev":false,"next":false},"headers":[],"relativePath":"garden/personality/index.md","filePath":"garden/personality/index.md"}'),u={name:"garden/personality/index.md"},v=Object.assign(u,{setup(c){const i=o();return(m,y)=>(l(),n("div",null,[p,e("p",null,[s("143 words, ~1 minute read. "),e("span",{innerHTML:t(a)[`site/${t(i).page.value.relativePath}`]},null,8,d)]),h]))}});export{g as __pageData,v as default}; +import{d as a}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as n,Q as e,K as s,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const p=e("h1",{class:"p-name"},"Personality",-1),d=["innerHTML"],h=r("",3),g=JSON.parse('{"title":"Personality","description":"","frontmatter":{"public":"true","slug":"personality","title":"Personality","prev":false,"next":false},"headers":[],"relativePath":"garden/personality/index.md","filePath":"garden/personality/index.md"}'),u={name:"garden/personality/index.md"},v=Object.assign(u,{setup(c){const i=o();return(m,y)=>(l(),n("div",null,[p,e("p",null,[s("143 words, ~1 minute read. "),e("span",{innerHTML:t(a)[`site/${t(i).page.value.relativePath}`]},null,8,d)]),h]))}});export{g as __pageData,v as default}; diff --git a/assets/garden_planar-pioneers_index.md.7VDRFjaj.js b/assets/garden_planar-pioneers_index.md.k-RkmoSH.js similarity index 95% rename from assets/garden_planar-pioneers_index.md.7VDRFjaj.js rename to assets/garden_planar-pioneers_index.md.k-RkmoSH.js index f02654157..0eb7a4488 100644 --- a/assets/garden_planar-pioneers_index.md.7VDRFjaj.js +++ b/assets/garden_planar-pioneers_index.md.k-RkmoSH.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as n,Q as e,K as o,u as a,ag as p,p as i}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Planar Pioneers",-1),d=["innerHTML"],c=p('
Tags:My ProjectsProfectus

Play it here!

An Open Source game designed to show off Profectus' dynamic layer system!

The TV Tropes page on this game mentions some of the cool things about this game

',5),P=JSON.parse('{"title":"Planar Pioneers","description":"","frontmatter":{"public":"true","slug":"planar-pioneers","tags":["My Projects","Profectus"],"title":"Planar Pioneers","prev":false,"next":false},"headers":[],"relativePath":"garden/planar-pioneers/index.md","filePath":"garden/planar-pioneers/index.md"}'),_={name:"garden/planar-pioneers/index.md"},T=Object.assign(_,{setup(m){const r=s();return(h,f)=>(i(),n("div",null,[l,e("p",null,[o("25 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,d)]),c]))}});export{P as __pageData,T as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as n,Q as e,K as o,u as a,ag as p,p as i}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Planar Pioneers",-1),d=["innerHTML"],c=p('
Tags:My ProjectsProfectus

Play it here!

An Open Source game designed to show off Profectus' dynamic layer system!

The TV Tropes page on this game mentions some of the cool things about this game

',5),P=JSON.parse('{"title":"Planar Pioneers","description":"","frontmatter":{"public":"true","slug":"planar-pioneers","tags":["My Projects","Profectus"],"title":"Planar Pioneers","prev":false,"next":false},"headers":[],"relativePath":"garden/planar-pioneers/index.md","filePath":"garden/planar-pioneers/index.md"}'),_={name:"garden/planar-pioneers/index.md"},T=Object.assign(_,{setup(m){const r=s();return(h,f)=>(i(),n("div",null,[l,e("p",null,[o("25 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,d)]),c]))}});export{P as __pageData,T as default}; diff --git a/assets/garden_planar-pioneers_index.md.7VDRFjaj.lean.js b/assets/garden_planar-pioneers_index.md.k-RkmoSH.lean.js similarity index 92% rename from assets/garden_planar-pioneers_index.md.7VDRFjaj.lean.js rename to assets/garden_planar-pioneers_index.md.k-RkmoSH.lean.js index 6f1c83c53..b3a4a02fc 100644 --- a/assets/garden_planar-pioneers_index.md.7VDRFjaj.lean.js +++ b/assets/garden_planar-pioneers_index.md.k-RkmoSH.lean.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as n,Q as e,K as o,u as a,ag as p,p as i}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Planar Pioneers",-1),d=["innerHTML"],c=p("",5),P=JSON.parse('{"title":"Planar Pioneers","description":"","frontmatter":{"public":"true","slug":"planar-pioneers","tags":["My Projects","Profectus"],"title":"Planar Pioneers","prev":false,"next":false},"headers":[],"relativePath":"garden/planar-pioneers/index.md","filePath":"garden/planar-pioneers/index.md"}'),_={name:"garden/planar-pioneers/index.md"},T=Object.assign(_,{setup(m){const r=s();return(h,f)=>(i(),n("div",null,[l,e("p",null,[o("25 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,d)]),c]))}});export{P as __pageData,T as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as n,Q as e,K as o,u as a,ag as p,p as i}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Planar Pioneers",-1),d=["innerHTML"],c=p("",5),P=JSON.parse('{"title":"Planar Pioneers","description":"","frontmatter":{"public":"true","slug":"planar-pioneers","tags":["My Projects","Profectus"],"title":"Planar Pioneers","prev":false,"next":false},"headers":[],"relativePath":"garden/planar-pioneers/index.md","filePath":"garden/planar-pioneers/index.md"}'),_={name:"garden/planar-pioneers/index.md"},T=Object.assign(_,{setup(m){const r=s();return(h,f)=>(i(),n("div",null,[l,e("p",null,[o("25 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,d)]),c]))}});export{P as __pageData,T as default}; diff --git a/assets/garden_police-abolition_index.md.CU68gI68.js b/assets/garden_police-abolition_index.md.CeqMJoCo.js similarity index 99% rename from assets/garden_police-abolition_index.md.CU68gI68.js rename to assets/garden_police-abolition_index.md.CeqMJoCo.js index 0d2dd198e..862f2bf5b 100644 --- a/assets/garden_police-abolition_index.md.CU68gI68.js +++ b/assets/garden_police-abolition_index.md.CeqMJoCo.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as r,q as o,Q as e,K as n,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Police Abolition",-1),h=["innerHTML"],p=s('
Referenced by:AnarchismConsensus DemocracyMy Political Beliefs

I'm a supporter of the police abolition movement, which calls for police and prisons to be abolished. It argues that there are many inherent problems with policing and incarcerating people that cannot be fixed with just further training or restrictions - the entire system must be entirely abolished. In this way, it is a more extreme version of the police reform or defund the police movements. The movement also posits that there are alternatives to policing and incarceration that can be more effective at reducing crime.

What is police abolition?

Just to make sure we're all on the same page as to what police abolition means and involves, I'll be using some definitions from Critical Reach:

The prison industrial complex (PIC) is a term we use to describe the overlapping interests of government and industry that use surveillance, policing, and imprisonment as solutions to economic, social and political problems.

PIC abolition is a political vision with the goal of eliminating imprisonment, policing, and surveillance and creating lasting alternatives to punishment and imprisonment.

I'll generally just say police or prison abolition, but I'm still referring to pieces of PIC abolition.

Why abolish police?

There are a variety of reasons for abolishing the police, from its controversial origins to its pervasive discrimination to its overall lack of effectiveness. Ultimately though, I would argue this movement stems from anarchistic principles and values. Anarchism posits that no person should hold power over another (a simplification sufficient for this document), which would include the use of force or imprisonment. Anarchists argue the State has no right to exist, let alone that it has no right to call it's violence legitimate. From this premise, any form of policing or incarceration is unjust. However, let's explore additional problems within the specific context of the US:

Origins of policing

The initial implementation of the police in the US was inspired both by the systems they experienced across the pond as well as the bands of slave catchers that were present at the time. The fact policing and incarceration as concepts had to be invented and introduced to people who were already existing just fine is telling enough, and the fact they were introduced to bring slaves back to their owners is even more telling. These origins have ingrained racism into the entire system, and they are still evident today when looking at racial profiling, incarceration rates, etc.

Throughout their history police have, in practice, protected "property" (which slaves were considered to be at the time), not people. In a broader sense, they were a tool of the capitalist elite. That's why the Supreme Court ruled that police do not actually have an obligation to protect nor serve citizens and why early cops were also strike breakers.

While the origins of an institution don't necessarily dictate how it is structured and operated hundreds of years later, they do give insight into how the institution was designed and what purposes/roles it was actually filling. Today, thanks to various forms of "copaganda" in media, there's rhetoric that people should support and appreciate the police, that they are fair and effective and protect us from crime and villainy. As we'll continue to describe, I think the police are much more similar to their roots than the fiction they're portrayed as.

Discriminating against the poor

The police are designed to reinforce the capitalist status quo; the "law and order" they uphold is less so to do with ensuring life is fair and safe for all, but rather to keep the working class in check so the capitalist class are safe and secure. This is most evident by looking at how many laws primarily affect the poor and how rarely laws are enforced when the perpetrator is a capitalist.

"The law, in its majestic equality, forbids rich and poor alike to sleep under bridges, to beg in the streets, and to steal their bread."
Anatole France

Property crime lead to over 750,000 arrests in 2019. Wage theft, which according to a 2014 study may account for up to $50 Billion stolen, is a civil matter that doesn't lead to any arrests. In fact, white collar misdeeds are often not classified as criminal offenses - that's why after the 2008 housing market crash that devastated millions, only 1 banker was arrested and it was for something relatively trivial compared to the actual crash.

Even when it is a criminal offense, white collar crime is rarely punished. A lot of societal elites get away with horrendous misdeeds essentially out in the open. In fact, prosecuting the rich is so out of the norm that a rookie cop arresting Justin Timberlake caused a kerfuffle online because of just how much people like Justin aren't supposed to get arrested.

As a side note, there's a double standard here where rich are treated differently from poor people when they're the perpetrator of the crime, but not when they're the victim. If you look online for opinions on whether stealing from the rich to give to the poor is actually justified, you'll get a fairly overwhelming response that "theft is theft" and the context within which the theft occurred is not relevant. I think it's important to keep in mind the context of how the rich have rigged the system to consolidate wealth in the hands of as few as possible, and the impact that has had on society. On other issues, people are just fine dealing with nuance, like how violence is justified when it's self defense. I believe our society has been deliberately shaped to have the value that the victim being poor vs rich shouldn't matter, specifically because it benefits the rich.

Racism

The PIC has not shaken off the racism ingrained within its roots. Arrests are not proportional to actual crime rates, disproportionately affecting people of color - including when the cops themselves are black. Additionally, laws have been introduced throughout the history of the US that were explicitly designed to affect minorities, like the Jim Crow laws or the entirety of Nixon's war on drugs (a victimless "crime").

The police are an active threat to black people, who are 3x as likely to be shot and killed from the police without presenting a threat. That makes cops people to be avoided and who cannot be relied upon in an emergency. Even calling the police yourself is a risk.

Cost

The government spends hundreds of billions of dollars on the incarceral system, an absolutely profound amount of money that could make enormous differences had it been put to social services instead.

The prison system has for profit private prisons with minimum occupancy clauses that cost taxpayers money if we don't arrest enough people. This is a gross financial incentive to arrest more people, and it disincentivizes actual rehabilitation. These contribute to the US' incredibly high recidivism rates.

Ineffectiveness at stopping crime

Most crimes performed are out of necessity, not malice. For example, few would be stealing baby formula or bread if it weren't for our economic system introducing artificial scarcity to keep prices going up.

America has the highest incarceration rate in the world, for a variety of the reasons mentioned in this document. Yet, the fear of punishment and imprisonment does not seem to have the effect of discouraging crime. Indeed, increasing incarceration does not decrease crime.

Criminal officers

Officers themselves perpetrate a lot of crime (and I suspect there's a lot of police crimes that doesn't get reported), including 1/3 of all murders that involve a stranger, and are typically protected by a corrupt system with the strongest union in the nation (often attributed to the union serving the interests of capital, rather than workers like labor unions). In particular, officers have incredibly high rates of interspousal conflicts. Therefore, abolitionism is the only solution to gender-based violence.

How to abolish police

There are many ways to reduce the need of police until it's eventually zero. Immediately, perpetratore of victimless crimes should be let out of prison. You can also reduce most root causes of crime, rather than spending the money on incarcerating the perpetrators.

Crime reduction

Abolitionists still want to ensure public safety, just not through policing and incarceration. They believe, since most crime is not born of malice, that improving society by ensuring everyone's needs are met would evaporate the majority of crimes as well - at least as many as are prevented by the current system. Police are incredibly over funded, enough to buy things like surplus tanks from the US military. That money can instead go to social programs that would solve the root causes that lead to crimes.

Societies can and will find alternative ways of preventing any specific crime. An often used example is if you have a drunk friend who is about to drive home, you typically will help get them a ride (driving yourself if you're sober, or calling them a cab or uber otherwise) rather than calling the police on them. Abolitionism finds policing as only required by those who lack the political imagination to find other solutions - basically, cure the diseases rather than treat the symptoms. At a systemic level, drunk driving can be reduced or eliminated by improving public transit.

Dangerous incidents

With the police abolished, there are likely to still be cases where an individual is a danger to themselves or others. For these situations, there are ideas on how to resolve it without state sanctioned violence, that typically focus on local communities setting up alternative resources. Mobile crisis teams are one such alternative, although not without similar concerns regarding their authority to forcibly incarcerate people in mental health hospitals. There are a lot of alternatives out there, but they're typically specific to local communities and don't really have a "one size fits all" solution. Here's an article about a couple such initiatives, and this article linked earlier also discusses some specific local initiatives.

Another criticism of prison abolitionism specifically is What do you do with the murderers and rapists?, but as that article describes: we already don't incarcerate many murderers and rapists, especially the significant amount of murderers and rapists who are also officers. It argues the incarceral system already fails in this regard, and focuses on punishing the perpetrator rather than helping the victims, which is something we could do without incarceration.

Consequences

While punishments are not good deterrents, some consequences for crimes are still justified and can be enforced without requiring incarceration. A victim may be "made whole" (have the damage reversed to the best of our ability) at expense of the perpetrator, or the society itself (using resources its no longer spending on police or prison). If there's a material cause for the crime having taken place, e.g. a hungry person stealing food, those material conditions can be improved. For cases where the perpetrator is chronically exhibiting anti-social behavior, a trip to a rehabilitation facility, which would be operated significantly differently from the PIC, could be warranted. Stuff like anger management courses or resources to help kick addictions would naturally still be present in a society without prisons.

Further reading

I have not finished reading it yet myself, but I recommend We Do This ‘Til We Free Us by Mariame Kaba based on this NBC article on the book and author.

How police make up the law by Philosophy Tube is a very well produced look at how police got their de facto supreme authority, and it's implications. They have several other videos on the police I recommend, and any other videos they've made 😃.

Abolition notes contains a lot of public documents and guides on prison abolition and related leftist causes.

',45),w=JSON.parse('{"title":"Police Abolition","description":"","frontmatter":{"public":"true","slug":"police-abolition","title":"Police Abolition","prev":false,"next":false},"headers":[],"relativePath":"garden/police-abolition/index.md","filePath":"garden/police-abolition/index.md"}'),d={name:"garden/police-abolition/index.md"},y=Object.assign(d,{setup(u){const a=r();return(m,f)=>(l(),o("div",null,[c,e("p",null,[n("1641 words, ~9 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,h)]),p]))}});export{w as __pageData,y as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as r,q as o,Q as e,K as n,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Police Abolition",-1),h=["innerHTML"],p=s('
Referenced by:AnarchismConsensus DemocracyMy Political Beliefs

I'm a supporter of the police abolition movement, which calls for police and prisons to be abolished. It argues that there are many inherent problems with policing and incarcerating people that cannot be fixed with just further training or restrictions - the entire system must be entirely abolished. In this way, it is a more extreme version of the police reform or defund the police movements. The movement also posits that there are alternatives to policing and incarceration that can be more effective at reducing crime.

What is police abolition?

Just to make sure we're all on the same page as to what police abolition means and involves, I'll be using some definitions from Critical Reach:

The prison industrial complex (PIC) is a term we use to describe the overlapping interests of government and industry that use surveillance, policing, and imprisonment as solutions to economic, social and political problems.

PIC abolition is a political vision with the goal of eliminating imprisonment, policing, and surveillance and creating lasting alternatives to punishment and imprisonment.

I'll generally just say police or prison abolition, but I'm still referring to pieces of PIC abolition.

Why abolish police?

There are a variety of reasons for abolishing the police, from its controversial origins to its pervasive discrimination to its overall lack of effectiveness. Ultimately though, I would argue this movement stems from anarchistic principles and values. Anarchism posits that no person should hold power over another (a simplification sufficient for this document), which would include the use of force or imprisonment. Anarchists argue the State has no right to exist, let alone that it has no right to call it's violence legitimate. From this premise, any form of policing or incarceration is unjust. However, let's explore additional problems within the specific context of the US:

Origins of policing

The initial implementation of the police in the US was inspired both by the systems they experienced across the pond as well as the bands of slave catchers that were present at the time. The fact policing and incarceration as concepts had to be invented and introduced to people who were already existing just fine is telling enough, and the fact they were introduced to bring slaves back to their owners is even more telling. These origins have ingrained racism into the entire system, and they are still evident today when looking at racial profiling, incarceration rates, etc.

Throughout their history police have, in practice, protected "property" (which slaves were considered to be at the time), not people. In a broader sense, they were a tool of the capitalist elite. That's why the Supreme Court ruled that police do not actually have an obligation to protect nor serve citizens and why early cops were also strike breakers.

While the origins of an institution don't necessarily dictate how it is structured and operated hundreds of years later, they do give insight into how the institution was designed and what purposes/roles it was actually filling. Today, thanks to various forms of "copaganda" in media, there's rhetoric that people should support and appreciate the police, that they are fair and effective and protect us from crime and villainy. As we'll continue to describe, I think the police are much more similar to their roots than the fiction they're portrayed as.

Discriminating against the poor

The police are designed to reinforce the capitalist status quo; the "law and order" they uphold is less so to do with ensuring life is fair and safe for all, but rather to keep the working class in check so the capitalist class are safe and secure. This is most evident by looking at how many laws primarily affect the poor and how rarely laws are enforced when the perpetrator is a capitalist.

"The law, in its majestic equality, forbids rich and poor alike to sleep under bridges, to beg in the streets, and to steal their bread."
Anatole France

Property crime lead to over 750,000 arrests in 2019. Wage theft, which according to a 2014 study may account for up to $50 Billion stolen, is a civil matter that doesn't lead to any arrests. In fact, white collar misdeeds are often not classified as criminal offenses - that's why after the 2008 housing market crash that devastated millions, only 1 banker was arrested and it was for something relatively trivial compared to the actual crash.

Even when it is a criminal offense, white collar crime is rarely punished. A lot of societal elites get away with horrendous misdeeds essentially out in the open. In fact, prosecuting the rich is so out of the norm that a rookie cop arresting Justin Timberlake caused a kerfuffle online because of just how much people like Justin aren't supposed to get arrested.

As a side note, there's a double standard here where rich are treated differently from poor people when they're the perpetrator of the crime, but not when they're the victim. If you look online for opinions on whether stealing from the rich to give to the poor is actually justified, you'll get a fairly overwhelming response that "theft is theft" and the context within which the theft occurred is not relevant. I think it's important to keep in mind the context of how the rich have rigged the system to consolidate wealth in the hands of as few as possible, and the impact that has had on society. On other issues, people are just fine dealing with nuance, like how violence is justified when it's self defense. I believe our society has been deliberately shaped to have the value that the victim being poor vs rich shouldn't matter, specifically because it benefits the rich.

Racism

The PIC has not shaken off the racism ingrained within its roots. Arrests are not proportional to actual crime rates, disproportionately affecting people of color - including when the cops themselves are black. Additionally, laws have been introduced throughout the history of the US that were explicitly designed to affect minorities, like the Jim Crow laws or the entirety of Nixon's war on drugs (a victimless "crime").

The police are an active threat to black people, who are 3x as likely to be shot and killed from the police without presenting a threat. That makes cops people to be avoided and who cannot be relied upon in an emergency. Even calling the police yourself is a risk.

Cost

The government spends hundreds of billions of dollars on the incarceral system, an absolutely profound amount of money that could make enormous differences had it been put to social services instead.

The prison system has for profit private prisons with minimum occupancy clauses that cost taxpayers money if we don't arrest enough people. This is a gross financial incentive to arrest more people, and it disincentivizes actual rehabilitation. These contribute to the US' incredibly high recidivism rates.

Ineffectiveness at stopping crime

Most crimes performed are out of necessity, not malice. For example, few would be stealing baby formula or bread if it weren't for our economic system introducing artificial scarcity to keep prices going up.

America has the highest incarceration rate in the world, for a variety of the reasons mentioned in this document. Yet, the fear of punishment and imprisonment does not seem to have the effect of discouraging crime. Indeed, increasing incarceration does not decrease crime.

Criminal officers

Officers themselves perpetrate a lot of crime (and I suspect there's a lot of police crimes that doesn't get reported), including 1/3 of all murders that involve a stranger, and are typically protected by a corrupt system with the strongest union in the nation (often attributed to the union serving the interests of capital, rather than workers like labor unions). In particular, officers have incredibly high rates of interspousal conflicts. Therefore, abolitionism is the only solution to gender-based violence.

How to abolish police

There are many ways to reduce the need of police until it's eventually zero. Immediately, perpetratore of victimless crimes should be let out of prison. You can also reduce most root causes of crime, rather than spending the money on incarcerating the perpetrators.

Crime reduction

Abolitionists still want to ensure public safety, just not through policing and incarceration. They believe, since most crime is not born of malice, that improving society by ensuring everyone's needs are met would evaporate the majority of crimes as well - at least as many as are prevented by the current system. Police are incredibly over funded, enough to buy things like surplus tanks from the US military. That money can instead go to social programs that would solve the root causes that lead to crimes.

Societies can and will find alternative ways of preventing any specific crime. An often used example is if you have a drunk friend who is about to drive home, you typically will help get them a ride (driving yourself if you're sober, or calling them a cab or uber otherwise) rather than calling the police on them. Abolitionism finds policing as only required by those who lack the political imagination to find other solutions - basically, cure the diseases rather than treat the symptoms. At a systemic level, drunk driving can be reduced or eliminated by improving public transit.

Dangerous incidents

With the police abolished, there are likely to still be cases where an individual is a danger to themselves or others. For these situations, there are ideas on how to resolve it without state sanctioned violence, that typically focus on local communities setting up alternative resources. Mobile crisis teams are one such alternative, although not without similar concerns regarding their authority to forcibly incarcerate people in mental health hospitals. There are a lot of alternatives out there, but they're typically specific to local communities and don't really have a "one size fits all" solution. Here's an article about a couple such initiatives, and this article linked earlier also discusses some specific local initiatives.

Another criticism of prison abolitionism specifically is What do you do with the murderers and rapists?, but as that article describes: we already don't incarcerate many murderers and rapists, especially the significant amount of murderers and rapists who are also officers. It argues the incarceral system already fails in this regard, and focuses on punishing the perpetrator rather than helping the victims, which is something we could do without incarceration.

Consequences

While punishments are not good deterrents, some consequences for crimes are still justified and can be enforced without requiring incarceration. A victim may be "made whole" (have the damage reversed to the best of our ability) at expense of the perpetrator, or the society itself (using resources its no longer spending on police or prison). If there's a material cause for the crime having taken place, e.g. a hungry person stealing food, those material conditions can be improved. For cases where the perpetrator is chronically exhibiting anti-social behavior, a trip to a rehabilitation facility, which would be operated significantly differently from the PIC, could be warranted. Stuff like anger management courses or resources to help kick addictions would naturally still be present in a society without prisons.

Further reading

I have not finished reading it yet myself, but I recommend We Do This ‘Til We Free Us by Mariame Kaba based on this NBC article on the book and author.

How police make up the law by Philosophy Tube is a very well produced look at how police got their de facto supreme authority, and it's implications. They have several other videos on the police I recommend, and any other videos they've made 😃.

Abolition notes contains a lot of public documents and guides on prison abolition and related leftist causes.

',45),w=JSON.parse('{"title":"Police Abolition","description":"","frontmatter":{"public":"true","slug":"police-abolition","title":"Police Abolition","prev":false,"next":false},"headers":[],"relativePath":"garden/police-abolition/index.md","filePath":"garden/police-abolition/index.md"}'),d={name:"garden/police-abolition/index.md"},y=Object.assign(d,{setup(u){const a=r();return(m,f)=>(l(),o("div",null,[c,e("p",null,[n("1641 words, ~9 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,h)]),p]))}});export{w as __pageData,y as default}; diff --git a/assets/garden_police-abolition_index.md.CU68gI68.lean.js b/assets/garden_police-abolition_index.md.CeqMJoCo.lean.js similarity index 91% rename from assets/garden_police-abolition_index.md.CU68gI68.lean.js rename to assets/garden_police-abolition_index.md.CeqMJoCo.lean.js index e8f69f857..bcbc2909c 100644 --- a/assets/garden_police-abolition_index.md.CU68gI68.lean.js +++ b/assets/garden_police-abolition_index.md.CeqMJoCo.lean.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as r,q as o,Q as e,K as n,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Police Abolition",-1),h=["innerHTML"],p=s("",45),w=JSON.parse('{"title":"Police Abolition","description":"","frontmatter":{"public":"true","slug":"police-abolition","title":"Police Abolition","prev":false,"next":false},"headers":[],"relativePath":"garden/police-abolition/index.md","filePath":"garden/police-abolition/index.md"}'),d={name:"garden/police-abolition/index.md"},y=Object.assign(d,{setup(u){const a=r();return(m,f)=>(l(),o("div",null,[c,e("p",null,[n("1641 words, ~9 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,h)]),p]))}});export{w as __pageData,y as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as r,q as o,Q as e,K as n,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Police Abolition",-1),h=["innerHTML"],p=s("",45),w=JSON.parse('{"title":"Police Abolition","description":"","frontmatter":{"public":"true","slug":"police-abolition","title":"Police Abolition","prev":false,"next":false},"headers":[],"relativePath":"garden/police-abolition/index.md","filePath":"garden/police-abolition/index.md"}'),d={name:"garden/police-abolition/index.md"},y=Object.assign(d,{setup(u){const a=r();return(m,f)=>(l(),o("div",null,[c,e("p",null,[n("1641 words, ~9 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,h)]),p]))}});export{w as __pageData,y as default}; diff --git a/assets/garden_political-quizzes_index.md.R467aSgs.js b/assets/garden_political-quizzes_index.md.C0oamyiX.js similarity index 99% rename from assets/garden_political-quizzes_index.md.R467aSgs.js rename to assets/garden_political-quizzes_index.md.C0oamyiX.js index 92175b17d..6e0367e95 100644 --- a/assets/garden_political-quizzes_index.md.R467aSgs.js +++ b/assets/garden_political-quizzes_index.md.C0oamyiX.js @@ -1 +1 @@ -import{M as a,q as s,Q as e,K as r,u as t,ag as o,p as n,az as l,aA as h,aB as u,aC as c,aD as p,aE as d,aF as m,aG as g,aH as f,aI as y,aJ as b,aK as v}from"./chunks/framework.Sr2_9k8k.js";import{d as q}from"./chunks/git.data.D-Ga3RhB.js";const _=e("h1",{class:"p-name"},"Political Quizzes",-1),k=["innerHTML"],w=o('

Political quizzes are a bit of a guilty pleasure of mine. I really enjoy getting my beliefs distilled into a handful of labels, and getting forced to think about issues I may not have thought about that thoroughly. I often take issue with the wording of various questions though, and certainly have opinions on some quizzes being better than others.

Ultimately, the reason I consider these quizzes a guilty pleasure is because the results shouldn't really be used for anything. I believe we should vote on the issues directly, and any form of Representative Democracy is an unnecessary abstraction. The labels may be useful as a mnemonic, but not as useful as the individual answers and the justifications behind those answers. Plus, people are going to interpret the questions differently, especially when it comes to understanding terms like liberalism, freedom, or merit.

With all that said, here I'll discuss some tests I've taken, the results I've gotten l, and my overall thoughts on it. I'll include the dates taken so they can map to My Political Journey.

Prism Political Quiz

Made by the six triangles creator, I really like this test! It actually might be my favorite. It novelly gives you multiple positions to take on a given issue, rather than a statement you can agree or disagree with. I overall really liked the choices, and nearly always felt one represented my views.

I like the results I got on 2024-09-06. I was surprised at my government value being just "direct democracy", when the way I define my views on Government in My Political Beliefs (at the time of taking the test), which I believe I reflected accurately in my responses here, would probably include at least some points on anarchism and confederationism. That said, I liked these results so much that they inspired me to write that page on my political beliefs, which takes clear inspiration from this test.

Six Triangles

I was intrigued by Six Triangles' idea of replacing axes with triangles, although some of the additional points seem a bit redundant, or just acted as a disguised additional axis. For example, the truth corner of personal freedom is not really related to the axis of freedom vs security. It could have easily been its own axis specific to misinformation. Similarly, I think the burden corner of equality is going to be highly correlated to their equality of opportunity score. Others, however, really benefit from the third point, like economy being split up into laissez faire capitalism, "well regulated" capitalism, and socialism.

Unfortunately, I found a lot of the questions to be poorly worded or vague. For example, I disagree with the statement "The government occasionally needs to do things which aren't popular for the good of its people" because popular isn't sufficient, but in a system that requires unanimity (or near unanimity), I'd argue everything that gets passed is for the good of the people, based off the values and considerations of those specific people. That nuance doesn't carry over if I just select "disagree" though. They also have the statement "Small government is usually better than big government" without any context for what big vs small mean in this context: number of employees? Amount of nationalized services? Number of constituents? Amount of regulations? This distinction matters for getting (more) accurate results.

The results from taking it on 2024-09-05 were quite satisfying to go through. I particularly enjoyed being called a "Fanatic anti-imperialist". The main score I disagreed with was the government triangle; I would've preferred a higher minarchy score.

SapplyValues

I took the SapplyValues quiz on 2024-05-07:

4Orbs

I took the 4Orbs quiz on 2023-07-09:

Spekr

I like that this quiz gives live feedback, as it helped me introspect on the differences between my self-reported positions versus positions political quizzes assign me (for example, I usually think I'm way closer to anarchist than these tests usually put me, although funnily enough this quiz probably gave me one of the strongest anarchist score of any test I've taken). I also like that the creator is an anarchist themselves, which is likely uncommon across political quiz writers. I also felt like a lot of the questions were phrased in quite interesting ways.

I took the spekr quiz on 2023-05-17:

isidewith

I really didn't like this quiz. I think its overly-constrained to the range of discussion considered politically viable in America, and therefore didn't ask any questions about abolishing the state or replacing corporations with worker's co-operatives. I disagree with my results here moreso than any other political quiz I've taken.

I took the isidewith quiz on 2023-05-03:

I got quite different results on 2016-10-30, pre-radicalization:

Political compass

I took the political compass quiz on 2023-02-19:

I'd gotten similar results on 2022-06-15:

9Axes

I only took the short version, but here are my results from taking the 9Axes quiz on 2022-06-15:

',39),A=JSON.parse('{"title":"Political Quizzes","description":"","frontmatter":{"public":"true","slug":"political-quizzes","title":"Political Quizzes","prev":false,"next":false},"headers":[],"relativePath":"garden/political-quizzes/index.md","filePath":"garden/political-quizzes/index.md"}'),I={name:"garden/political-quizzes/index.md"},j=Object.assign(I,{setup(z){const i=a();return(x,P)=>(n(),s("div",null,[_,e("p",null,[r("841 words, ~5 minute read. "),e("span",{innerHTML:t(q)[`site/${t(i).page.value.relativePath}`]},null,8,k)]),w]))}});export{A as __pageData,j as default}; +import{M as a,q as s,Q as e,K as r,u as t,ag as o,p as n,az as l,aA as h,aB as u,aC as c,aD as p,aE as d,aF as m,aG as g,aH as f,aI as y,aJ as b,aK as v}from"./chunks/framework.Sr2_9k8k.js";import{d as q}from"./chunks/git.data.BcrWSzMU.js";const _=e("h1",{class:"p-name"},"Political Quizzes",-1),k=["innerHTML"],w=o('

Political quizzes are a bit of a guilty pleasure of mine. I really enjoy getting my beliefs distilled into a handful of labels, and getting forced to think about issues I may not have thought about that thoroughly. I often take issue with the wording of various questions though, and certainly have opinions on some quizzes being better than others.

Ultimately, the reason I consider these quizzes a guilty pleasure is because the results shouldn't really be used for anything. I believe we should vote on the issues directly, and any form of Representative Democracy is an unnecessary abstraction. The labels may be useful as a mnemonic, but not as useful as the individual answers and the justifications behind those answers. Plus, people are going to interpret the questions differently, especially when it comes to understanding terms like liberalism, freedom, or merit.

With all that said, here I'll discuss some tests I've taken, the results I've gotten l, and my overall thoughts on it. I'll include the dates taken so they can map to My Political Journey.

Prism Political Quiz

Made by the six triangles creator, I really like this test! It actually might be my favorite. It novelly gives you multiple positions to take on a given issue, rather than a statement you can agree or disagree with. I overall really liked the choices, and nearly always felt one represented my views.

I like the results I got on 2024-09-06. I was surprised at my government value being just "direct democracy", when the way I define my views on Government in My Political Beliefs (at the time of taking the test), which I believe I reflected accurately in my responses here, would probably include at least some points on anarchism and confederationism. That said, I liked these results so much that they inspired me to write that page on my political beliefs, which takes clear inspiration from this test.

Six Triangles

I was intrigued by Six Triangles' idea of replacing axes with triangles, although some of the additional points seem a bit redundant, or just acted as a disguised additional axis. For example, the truth corner of personal freedom is not really related to the axis of freedom vs security. It could have easily been its own axis specific to misinformation. Similarly, I think the burden corner of equality is going to be highly correlated to their equality of opportunity score. Others, however, really benefit from the third point, like economy being split up into laissez faire capitalism, "well regulated" capitalism, and socialism.

Unfortunately, I found a lot of the questions to be poorly worded or vague. For example, I disagree with the statement "The government occasionally needs to do things which aren't popular for the good of its people" because popular isn't sufficient, but in a system that requires unanimity (or near unanimity), I'd argue everything that gets passed is for the good of the people, based off the values and considerations of those specific people. That nuance doesn't carry over if I just select "disagree" though. They also have the statement "Small government is usually better than big government" without any context for what big vs small mean in this context: number of employees? Amount of nationalized services? Number of constituents? Amount of regulations? This distinction matters for getting (more) accurate results.

The results from taking it on 2024-09-05 were quite satisfying to go through. I particularly enjoyed being called a "Fanatic anti-imperialist". The main score I disagreed with was the government triangle; I would've preferred a higher minarchy score.

SapplyValues

I took the SapplyValues quiz on 2024-05-07:

4Orbs

I took the 4Orbs quiz on 2023-07-09:

Spekr

I like that this quiz gives live feedback, as it helped me introspect on the differences between my self-reported positions versus positions political quizzes assign me (for example, I usually think I'm way closer to anarchist than these tests usually put me, although funnily enough this quiz probably gave me one of the strongest anarchist score of any test I've taken). I also like that the creator is an anarchist themselves, which is likely uncommon across political quiz writers. I also felt like a lot of the questions were phrased in quite interesting ways.

I took the spekr quiz on 2023-05-17:

isidewith

I really didn't like this quiz. I think its overly-constrained to the range of discussion considered politically viable in America, and therefore didn't ask any questions about abolishing the state or replacing corporations with worker's co-operatives. I disagree with my results here moreso than any other political quiz I've taken.

I took the isidewith quiz on 2023-05-03:

I got quite different results on 2016-10-30, pre-radicalization:

Political compass

I took the political compass quiz on 2023-02-19:

I'd gotten similar results on 2022-06-15:

9Axes

I only took the short version, but here are my results from taking the 9Axes quiz on 2022-06-15:

',39),A=JSON.parse('{"title":"Political Quizzes","description":"","frontmatter":{"public":"true","slug":"political-quizzes","title":"Political Quizzes","prev":false,"next":false},"headers":[],"relativePath":"garden/political-quizzes/index.md","filePath":"garden/political-quizzes/index.md"}'),I={name:"garden/political-quizzes/index.md"},j=Object.assign(I,{setup(z){const i=a();return(x,P)=>(n(),s("div",null,[_,e("p",null,[r("841 words, ~5 minute read. "),e("span",{innerHTML:t(q)[`site/${t(i).page.value.relativePath}`]},null,8,k)]),w]))}});export{A as __pageData,j as default}; diff --git a/assets/garden_political-quizzes_index.md.R467aSgs.lean.js b/assets/garden_political-quizzes_index.md.C0oamyiX.lean.js similarity index 92% rename from assets/garden_political-quizzes_index.md.R467aSgs.lean.js rename to assets/garden_political-quizzes_index.md.C0oamyiX.lean.js index 021915048..b3870155c 100644 --- a/assets/garden_political-quizzes_index.md.R467aSgs.lean.js +++ b/assets/garden_political-quizzes_index.md.C0oamyiX.lean.js @@ -1 +1 @@ -import{M as a,q as s,Q as e,K as r,u as t,ag as o,p as n,az as l,aA as h,aB as u,aC as c,aD as p,aE as d,aF as m,aG as g,aH as f,aI as y,aJ as b,aK as v}from"./chunks/framework.Sr2_9k8k.js";import{d as q}from"./chunks/git.data.D-Ga3RhB.js";const _=e("h1",{class:"p-name"},"Political Quizzes",-1),k=["innerHTML"],w=o("",39),A=JSON.parse('{"title":"Political Quizzes","description":"","frontmatter":{"public":"true","slug":"political-quizzes","title":"Political Quizzes","prev":false,"next":false},"headers":[],"relativePath":"garden/political-quizzes/index.md","filePath":"garden/political-quizzes/index.md"}'),I={name:"garden/political-quizzes/index.md"},j=Object.assign(I,{setup(z){const i=a();return(x,P)=>(n(),s("div",null,[_,e("p",null,[r("841 words, ~5 minute read. "),e("span",{innerHTML:t(q)[`site/${t(i).page.value.relativePath}`]},null,8,k)]),w]))}});export{A as __pageData,j as default}; +import{M as a,q as s,Q as e,K as r,u as t,ag as o,p as n,az as l,aA as h,aB as u,aC as c,aD as p,aE as d,aF as m,aG as g,aH as f,aI as y,aJ as b,aK as v}from"./chunks/framework.Sr2_9k8k.js";import{d as q}from"./chunks/git.data.BcrWSzMU.js";const _=e("h1",{class:"p-name"},"Political Quizzes",-1),k=["innerHTML"],w=o("",39),A=JSON.parse('{"title":"Political Quizzes","description":"","frontmatter":{"public":"true","slug":"political-quizzes","title":"Political Quizzes","prev":false,"next":false},"headers":[],"relativePath":"garden/political-quizzes/index.md","filePath":"garden/political-quizzes/index.md"}'),I={name:"garden/political-quizzes/index.md"},j=Object.assign(I,{setup(z){const i=a();return(x,P)=>(n(),s("div",null,[_,e("p",null,[r("841 words, ~5 minute read. "),e("span",{innerHTML:t(q)[`site/${t(i).page.value.relativePath}`]},null,8,k)]),w]))}});export{A as __pageData,j as default}; diff --git a/assets/garden_pre-order-bonuses_index.md.BuOtoWs6.js b/assets/garden_pre-order-bonuses_index.md.C3KYEqnW.js similarity index 96% rename from assets/garden_pre-order-bonuses_index.md.BuOtoWs6.js rename to assets/garden_pre-order-bonuses_index.md.C3KYEqnW.js index 298976b13..7204f5d1a 100644 --- a/assets/garden_pre-order-bonuses_index.md.BuOtoWs6.js +++ b/assets/garden_pre-order-bonuses_index.md.C3KYEqnW.js @@ -1 +1 @@ -import{d as a}from"./chunks/git.data.D-Ga3RhB.js";import{M as t,q as r,Q as e,K as l,u as i,ag as o,p as n}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Pre-Order Bonuses",-1),u=["innerHTML"],c=o('
Referenced by:Video Game Monetization

Pre-order bonuses are benefits given to players who buy a game before it comes out

They primarily serve to benefit the company

  • People commit to buying before the embargo date passes
  • Heuristic of how well it'll sell after launch
  • Slight lead on return on investment
    • More significantly impacts indie studios, who will likely have less cash on hand
  • Companies make deals with storefronts to have exclusive bonuses, to drive customers to said storefronts

Common bonuses:

  • Digital goods:
  • Physical goods:
    • Typically pins, keychains, etc.
    • Typically only included in physical editions of the game
',7),y=JSON.parse('{"title":"Pre-Order Bonuses","description":"","frontmatter":{"public":"true","slug":"pre-order-bonuses","title":"Pre-Order Bonuses","prev":false,"next":false},"headers":[],"relativePath":"garden/pre-order-bonuses/index.md","filePath":"garden/pre-order-bonuses/index.md"}'),m={name:"garden/pre-order-bonuses/index.md"},b=Object.assign(m,{setup(p){const s=t();return(_,h)=>(n(),r("div",null,[d,e("p",null,[l("98 words, ~1 minute read. "),e("span",{innerHTML:i(a)[`site/${i(s).page.value.relativePath}`]},null,8,u)]),c]))}});export{y as __pageData,b as default}; +import{d as a}from"./chunks/git.data.BcrWSzMU.js";import{M as t,q as r,Q as e,K as l,u as i,ag as o,p as n}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Pre-Order Bonuses",-1),u=["innerHTML"],c=o('
Referenced by:Video Game Monetization

Pre-order bonuses are benefits given to players who buy a game before it comes out

They primarily serve to benefit the company

  • People commit to buying before the embargo date passes
  • Heuristic of how well it'll sell after launch
  • Slight lead on return on investment
    • More significantly impacts indie studios, who will likely have less cash on hand
  • Companies make deals with storefronts to have exclusive bonuses, to drive customers to said storefronts

Common bonuses:

  • Digital goods:
  • Physical goods:
    • Typically pins, keychains, etc.
    • Typically only included in physical editions of the game
',7),y=JSON.parse('{"title":"Pre-Order Bonuses","description":"","frontmatter":{"public":"true","slug":"pre-order-bonuses","title":"Pre-Order Bonuses","prev":false,"next":false},"headers":[],"relativePath":"garden/pre-order-bonuses/index.md","filePath":"garden/pre-order-bonuses/index.md"}'),m={name:"garden/pre-order-bonuses/index.md"},b=Object.assign(m,{setup(p){const s=t();return(_,h)=>(n(),r("div",null,[d,e("p",null,[l("98 words, ~1 minute read. "),e("span",{innerHTML:i(a)[`site/${i(s).page.value.relativePath}`]},null,8,u)]),c]))}});export{y as __pageData,b as default}; diff --git a/assets/garden_pre-order-bonuses_index.md.BuOtoWs6.lean.js b/assets/garden_pre-order-bonuses_index.md.C3KYEqnW.lean.js similarity index 92% rename from assets/garden_pre-order-bonuses_index.md.BuOtoWs6.lean.js rename to assets/garden_pre-order-bonuses_index.md.C3KYEqnW.lean.js index f4d19fc14..b012c6f3b 100644 --- a/assets/garden_pre-order-bonuses_index.md.BuOtoWs6.lean.js +++ b/assets/garden_pre-order-bonuses_index.md.C3KYEqnW.lean.js @@ -1 +1 @@ -import{d as a}from"./chunks/git.data.D-Ga3RhB.js";import{M as t,q as r,Q as e,K as l,u as i,ag as o,p as n}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Pre-Order Bonuses",-1),u=["innerHTML"],c=o("",7),y=JSON.parse('{"title":"Pre-Order Bonuses","description":"","frontmatter":{"public":"true","slug":"pre-order-bonuses","title":"Pre-Order Bonuses","prev":false,"next":false},"headers":[],"relativePath":"garden/pre-order-bonuses/index.md","filePath":"garden/pre-order-bonuses/index.md"}'),m={name:"garden/pre-order-bonuses/index.md"},b=Object.assign(m,{setup(p){const s=t();return(_,h)=>(n(),r("div",null,[d,e("p",null,[l("98 words, ~1 minute read. "),e("span",{innerHTML:i(a)[`site/${i(s).page.value.relativePath}`]},null,8,u)]),c]))}});export{y as __pageData,b as default}; +import{d as a}from"./chunks/git.data.BcrWSzMU.js";import{M as t,q as r,Q as e,K as l,u as i,ag as o,p as n}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Pre-Order Bonuses",-1),u=["innerHTML"],c=o("",7),y=JSON.parse('{"title":"Pre-Order Bonuses","description":"","frontmatter":{"public":"true","slug":"pre-order-bonuses","title":"Pre-Order Bonuses","prev":false,"next":false},"headers":[],"relativePath":"garden/pre-order-bonuses/index.md","filePath":"garden/pre-order-bonuses/index.md"}'),m={name:"garden/pre-order-bonuses/index.md"},b=Object.assign(m,{setup(p){const s=t();return(_,h)=>(n(),r("div",null,[d,e("p",null,[l("98 words, ~1 minute read. "),e("span",{innerHTML:i(a)[`site/${i(s).page.value.relativePath}`]},null,8,u)]),c]))}});export{y as __pageData,b as default}; diff --git a/assets/garden_premium-currency_index.md.ChZ8mdPg.js b/assets/garden_premium-currency_index.md.Bnxgz6Mq.js similarity index 95% rename from assets/garden_premium-currency_index.md.ChZ8mdPg.js rename to assets/garden_premium-currency_index.md.Bnxgz6Mq.js index 824101d0a..6475ae340 100644 --- a/assets/garden_premium-currency_index.md.ChZ8mdPg.js +++ b/assets/garden_premium-currency_index.md.Bnxgz6Mq.js @@ -1 +1 @@ -import{d as s}from"./chunks/git.data.D-Ga3RhB.js";import{M as t,q as n,Q as e,K as i,u as r,ag as o,p as c}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Premium Currency",-1),u=["innerHTML"],d=o('
Referenced by:Pre-Order Bonuses

A popular form of MTX where instead of receiving a useful item or effect directly, you receive a currency that is then spent on an in game store

Reasons companies use them

  • Abstracts the real world price of items
    • No strict conversion ratio
    • Discounts for bulk purchasing
    • Small amounts given for free based on story progression or watching ads
  • Consolidates smaller purchases into a larger one (decreasing friction of individual purchases)
',5),y=JSON.parse('{"title":"Premium Currency","description":"","frontmatter":{"public":"true","slug":"premium-currency","title":"Premium Currency","prev":false,"next":false},"headers":[],"relativePath":"garden/premium-currency/index.md","filePath":"garden/premium-currency/index.md"}'),m={name:"garden/premium-currency/index.md"},v=Object.assign(m,{setup(p){const a=t();return(_,f)=>(c(),n("div",null,[l,e("p",null,[i("71 words, ~0 minute read. "),e("span",{innerHTML:r(s)[`site/${r(a).page.value.relativePath}`]},null,8,u)]),d]))}});export{y as __pageData,v as default}; +import{d as s}from"./chunks/git.data.BcrWSzMU.js";import{M as t,q as n,Q as e,K as i,u as r,ag as o,p as c}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Premium Currency",-1),u=["innerHTML"],d=o('
Referenced by:Pre-Order Bonuses

A popular form of MTX where instead of receiving a useful item or effect directly, you receive a currency that is then spent on an in game store

Reasons companies use them

  • Abstracts the real world price of items
    • No strict conversion ratio
    • Discounts for bulk purchasing
    • Small amounts given for free based on story progression or watching ads
  • Consolidates smaller purchases into a larger one (decreasing friction of individual purchases)
',5),y=JSON.parse('{"title":"Premium Currency","description":"","frontmatter":{"public":"true","slug":"premium-currency","title":"Premium Currency","prev":false,"next":false},"headers":[],"relativePath":"garden/premium-currency/index.md","filePath":"garden/premium-currency/index.md"}'),m={name:"garden/premium-currency/index.md"},v=Object.assign(m,{setup(p){const a=t();return(_,f)=>(c(),n("div",null,[l,e("p",null,[i("71 words, ~0 minute read. "),e("span",{innerHTML:r(s)[`site/${r(a).page.value.relativePath}`]},null,8,u)]),d]))}});export{y as __pageData,v as default}; diff --git a/assets/garden_premium-currency_index.md.ChZ8mdPg.lean.js b/assets/garden_premium-currency_index.md.Bnxgz6Mq.lean.js similarity index 91% rename from assets/garden_premium-currency_index.md.ChZ8mdPg.lean.js rename to assets/garden_premium-currency_index.md.Bnxgz6Mq.lean.js index 91ed7a2e8..c32bb219e 100644 --- a/assets/garden_premium-currency_index.md.ChZ8mdPg.lean.js +++ b/assets/garden_premium-currency_index.md.Bnxgz6Mq.lean.js @@ -1 +1 @@ -import{d as s}from"./chunks/git.data.D-Ga3RhB.js";import{M as t,q as n,Q as e,K as i,u as r,ag as o,p as c}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Premium Currency",-1),u=["innerHTML"],d=o("",5),y=JSON.parse('{"title":"Premium Currency","description":"","frontmatter":{"public":"true","slug":"premium-currency","title":"Premium Currency","prev":false,"next":false},"headers":[],"relativePath":"garden/premium-currency/index.md","filePath":"garden/premium-currency/index.md"}'),m={name:"garden/premium-currency/index.md"},v=Object.assign(m,{setup(p){const a=t();return(_,f)=>(c(),n("div",null,[l,e("p",null,[i("71 words, ~0 minute read. "),e("span",{innerHTML:r(s)[`site/${r(a).page.value.relativePath}`]},null,8,u)]),d]))}});export{y as __pageData,v as default}; +import{d as s}from"./chunks/git.data.BcrWSzMU.js";import{M as t,q as n,Q as e,K as i,u as r,ag as o,p as c}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Premium Currency",-1),u=["innerHTML"],d=o("",5),y=JSON.parse('{"title":"Premium Currency","description":"","frontmatter":{"public":"true","slug":"premium-currency","title":"Premium Currency","prev":false,"next":false},"headers":[],"relativePath":"garden/premium-currency/index.md","filePath":"garden/premium-currency/index.md"}'),m={name:"garden/premium-currency/index.md"},v=Object.assign(m,{setup(p){const a=t();return(_,f)=>(c(),n("div",null,[l,e("p",null,[i("71 words, ~0 minute read. "),e("span",{innerHTML:r(s)[`site/${r(a).page.value.relativePath}`]},null,8,u)]),d]))}});export{y as __pageData,v as default}; diff --git a/assets/garden_prescriptivism-vs-descriptivism_index.md.Z9HaEgJU.js b/assets/garden_prescriptivism-vs-descriptivism_index.md.D490ZQQV.js similarity index 97% rename from assets/garden_prescriptivism-vs-descriptivism_index.md.Z9HaEgJU.js rename to assets/garden_prescriptivism-vs-descriptivism_index.md.D490ZQQV.js index b0a8f90ee..89c62f5d6 100644 --- a/assets/garden_prescriptivism-vs-descriptivism_index.md.Z9HaEgJU.js +++ b/assets/garden_prescriptivism-vs-descriptivism_index.md.D490ZQQV.js @@ -1 +1 @@ -import{d as s}from"./chunks/git.data.D-Ga3RhB.js";import{M as r,q as a,Q as e,K as n,u as t,ag as o,p as c}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Prescriptivism vs Descriptivism",-1),h=["innerHTML"],p=o('
Referenced by:Social Constructs

These two terms refer to how words are defined. Prescriptivism is where definitions are written by an authority of some sort and users of the language are supposed to respect that definition, or else they are incorrect. Prescriptivism defines a truth, a boundary on what is allowed. Descriptivism, on the other hand, argues definitions should be based on how the word is currently being used. Someone using it differently is not wrong, they're just part of the normal process through which definitions can change. Descriptivism, therefore, does not define an objective truth. A notable example of this dichotomy is the definition of "literally". It was defined as meaning something that is to be taken at face value, but dictionaries have found justification for it having a second, near opposite, definition.

I'm fairly against prescriptivism, but acknowledge the argument that words are more useful when their definitions don't change underneath you, especially in cases where the word can now ambiguously refer to the opposite of one of its other definitions. However, the cultural change in definitions happens regardless, so I think it's important to be able to analyze how words are being used and decide if and when it makes sense to update those definitions. I feel the same way about all Social Constructs , which language is just one of.

Dictionaries take a stance in between the two extremes - both becoming an authoritative (and therefore prescriptive) source of definitions, but updating them as deemed necessary to more closely match their real-world uses.

',5),w=JSON.parse('{"title":"Prescriptivism vs Descriptivism","description":"","frontmatter":{"alias":"Prescriptivism, Descriptivism, Prescriptivism or Descriptivism","public":"true","slug":"prescriptivism-vs-descriptivism","title":"Prescriptivism vs Descriptivism","prev":false,"next":false},"headers":[],"relativePath":"garden/prescriptivism-vs-descriptivism/index.md","filePath":"garden/prescriptivism-vs-descriptivism/index.md"}'),m={name:"garden/prescriptivism-vs-descriptivism/index.md"},_=Object.assign(m,{setup(l){const i=r();return(u,f)=>(c(),a("div",null,[d,e("p",null,[n("256 words, ~1 minute read. "),e("span",{innerHTML:t(s)[`site/${t(i).page.value.relativePath}`]},null,8,h)]),p]))}});export{w as __pageData,_ as default}; +import{d as s}from"./chunks/git.data.BcrWSzMU.js";import{M as r,q as a,Q as e,K as n,u as t,ag as o,p as c}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Prescriptivism vs Descriptivism",-1),h=["innerHTML"],p=o('
Referenced by:Social Constructs

These two terms refer to how words are defined. Prescriptivism is where definitions are written by an authority of some sort and users of the language are supposed to respect that definition, or else they are incorrect. Prescriptivism defines a truth, a boundary on what is allowed. Descriptivism, on the other hand, argues definitions should be based on how the word is currently being used. Someone using it differently is not wrong, they're just part of the normal process through which definitions can change. Descriptivism, therefore, does not define an objective truth. A notable example of this dichotomy is the definition of "literally". It was defined as meaning something that is to be taken at face value, but dictionaries have found justification for it having a second, near opposite, definition.

I'm fairly against prescriptivism, but acknowledge the argument that words are more useful when their definitions don't change underneath you, especially in cases where the word can now ambiguously refer to the opposite of one of its other definitions. However, the cultural change in definitions happens regardless, so I think it's important to be able to analyze how words are being used and decide if and when it makes sense to update those definitions. I feel the same way about all Social Constructs , which language is just one of.

Dictionaries take a stance in between the two extremes - both becoming an authoritative (and therefore prescriptive) source of definitions, but updating them as deemed necessary to more closely match their real-world uses.

',5),w=JSON.parse('{"title":"Prescriptivism vs Descriptivism","description":"","frontmatter":{"alias":"Prescriptivism, Descriptivism, Prescriptivism or Descriptivism","public":"true","slug":"prescriptivism-vs-descriptivism","title":"Prescriptivism vs Descriptivism","prev":false,"next":false},"headers":[],"relativePath":"garden/prescriptivism-vs-descriptivism/index.md","filePath":"garden/prescriptivism-vs-descriptivism/index.md"}'),m={name:"garden/prescriptivism-vs-descriptivism/index.md"},_=Object.assign(m,{setup(l){const i=r();return(u,f)=>(c(),a("div",null,[d,e("p",null,[n("256 words, ~1 minute read. "),e("span",{innerHTML:t(s)[`site/${t(i).page.value.relativePath}`]},null,8,h)]),p]))}});export{w as __pageData,_ as default}; diff --git a/assets/garden_prescriptivism-vs-descriptivism_index.md.Z9HaEgJU.lean.js b/assets/garden_prescriptivism-vs-descriptivism_index.md.D490ZQQV.lean.js similarity index 93% rename from assets/garden_prescriptivism-vs-descriptivism_index.md.Z9HaEgJU.lean.js rename to assets/garden_prescriptivism-vs-descriptivism_index.md.D490ZQQV.lean.js index 11f78bcc6..aa19560ea 100644 --- a/assets/garden_prescriptivism-vs-descriptivism_index.md.Z9HaEgJU.lean.js +++ b/assets/garden_prescriptivism-vs-descriptivism_index.md.D490ZQQV.lean.js @@ -1 +1 @@ -import{d as s}from"./chunks/git.data.D-Ga3RhB.js";import{M as r,q as a,Q as e,K as n,u as t,ag as o,p as c}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Prescriptivism vs Descriptivism",-1),h=["innerHTML"],p=o("",5),w=JSON.parse('{"title":"Prescriptivism vs Descriptivism","description":"","frontmatter":{"alias":"Prescriptivism, Descriptivism, Prescriptivism or Descriptivism","public":"true","slug":"prescriptivism-vs-descriptivism","title":"Prescriptivism vs Descriptivism","prev":false,"next":false},"headers":[],"relativePath":"garden/prescriptivism-vs-descriptivism/index.md","filePath":"garden/prescriptivism-vs-descriptivism/index.md"}'),m={name:"garden/prescriptivism-vs-descriptivism/index.md"},_=Object.assign(m,{setup(l){const i=r();return(u,f)=>(c(),a("div",null,[d,e("p",null,[n("256 words, ~1 minute read. "),e("span",{innerHTML:t(s)[`site/${t(i).page.value.relativePath}`]},null,8,h)]),p]))}});export{w as __pageData,_ as default}; +import{d as s}from"./chunks/git.data.BcrWSzMU.js";import{M as r,q as a,Q as e,K as n,u as t,ag as o,p as c}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Prescriptivism vs Descriptivism",-1),h=["innerHTML"],p=o("",5),w=JSON.parse('{"title":"Prescriptivism vs Descriptivism","description":"","frontmatter":{"alias":"Prescriptivism, Descriptivism, Prescriptivism or Descriptivism","public":"true","slug":"prescriptivism-vs-descriptivism","title":"Prescriptivism vs Descriptivism","prev":false,"next":false},"headers":[],"relativePath":"garden/prescriptivism-vs-descriptivism/index.md","filePath":"garden/prescriptivism-vs-descriptivism/index.md"}'),m={name:"garden/prescriptivism-vs-descriptivism/index.md"},_=Object.assign(m,{setup(l){const i=r();return(u,f)=>(c(),a("div",null,[d,e("p",null,[n("256 words, ~1 minute read. "),e("span",{innerHTML:t(s)[`site/${t(i).page.value.relativePath}`]},null,8,h)]),p]))}});export{w as __pageData,_ as default}; diff --git a/assets/garden_profectus_index.md.CvajevSf.js b/assets/garden_profectus_index.md.CIxoSPG0.js similarity index 96% rename from assets/garden_profectus_index.md.CvajevSf.js rename to assets/garden_profectus_index.md.CIxoSPG0.js index e03fa379e..7e8d7e198 100644 --- a/assets/garden_profectus_index.md.CvajevSf.js +++ b/assets/garden_profectus_index.md.CIxoSPG0.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as s,Q as e,K as o,u as a,ag as i,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Profectus",-1),m=["innerHTML"],c=i('
Referenced by:Advent IncrementalPlanar Pioneers
Tagged by:Advent IncrementalKronosPlanar Pioneers
Tags:My Projects

Profectus is an Open Source game engine I made, loosely based on The Modding Tree by Acamaeda. It centers around using Vue's reactivity and is designed with the intent to not restrain developers into making games that only look or behave "one way". Also, technically it's more of a template (rather than engine) for making web games.

Games made with Profectus:

  • Everything in this garden tagged with this page!
  • The entries to the Profectus Creation Jam
  • Primordia by Jacorb
',7),y=JSON.parse('{"title":"Profectus","description":"","frontmatter":{"public":"true","slug":"profectus","tags":["My Projects"],"title":"Profectus","prev":false,"next":false},"headers":[],"relativePath":"garden/profectus/index.md","filePath":"garden/profectus/index.md"}'),u={name:"garden/profectus/index.md"},P=Object.assign(u,{setup(p){const r=n();return(g,h)=>(d(),s("div",null,[l,e("p",null,[o("27 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,m)]),c]))}});export{y as __pageData,P as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as s,Q as e,K as o,u as a,ag as i,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Profectus",-1),m=["innerHTML"],c=i('
Referenced by:Advent IncrementalPlanar Pioneers
Tagged by:Advent IncrementalKronosPlanar Pioneers
Tags:My Projects

Profectus is an Open Source game engine I made, loosely based on The Modding Tree by Acamaeda. It centers around using Vue's reactivity and is designed with the intent to not restrain developers into making games that only look or behave "one way". Also, technically it's more of a template (rather than engine) for making web games.

Games made with Profectus:

  • Everything in this garden tagged with this page!
  • The entries to the Profectus Creation Jam
  • Primordia by Jacorb
',7),y=JSON.parse('{"title":"Profectus","description":"","frontmatter":{"public":"true","slug":"profectus","tags":["My Projects"],"title":"Profectus","prev":false,"next":false},"headers":[],"relativePath":"garden/profectus/index.md","filePath":"garden/profectus/index.md"}'),u={name:"garden/profectus/index.md"},P=Object.assign(u,{setup(p){const r=n();return(g,h)=>(d(),s("div",null,[l,e("p",null,[o("27 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,m)]),c]))}});export{y as __pageData,P as default}; diff --git a/assets/garden_profectus_index.md.CvajevSf.lean.js b/assets/garden_profectus_index.md.CIxoSPG0.lean.js similarity index 91% rename from assets/garden_profectus_index.md.CvajevSf.lean.js rename to assets/garden_profectus_index.md.CIxoSPG0.lean.js index 8d386c2b0..7854f699e 100644 --- a/assets/garden_profectus_index.md.CvajevSf.lean.js +++ b/assets/garden_profectus_index.md.CIxoSPG0.lean.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as s,Q as e,K as o,u as a,ag as i,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Profectus",-1),m=["innerHTML"],c=i("",7),y=JSON.parse('{"title":"Profectus","description":"","frontmatter":{"public":"true","slug":"profectus","tags":["My Projects"],"title":"Profectus","prev":false,"next":false},"headers":[],"relativePath":"garden/profectus/index.md","filePath":"garden/profectus/index.md"}'),u={name:"garden/profectus/index.md"},P=Object.assign(u,{setup(p){const r=n();return(g,h)=>(d(),s("div",null,[l,e("p",null,[o("27 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,m)]),c]))}});export{y as __pageData,P as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as s,Q as e,K as o,u as a,ag as i,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Profectus",-1),m=["innerHTML"],c=i("",7),y=JSON.parse('{"title":"Profectus","description":"","frontmatter":{"public":"true","slug":"profectus","tags":["My Projects"],"title":"Profectus","prev":false,"next":false},"headers":[],"relativePath":"garden/profectus/index.md","filePath":"garden/profectus/index.md"}'),u={name:"garden/profectus/index.md"},P=Object.assign(u,{setup(p){const r=n();return(g,h)=>(d(),s("div",null,[l,e("p",null,[o("27 words, ~0 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,m)]),c]))}});export{y as __pageData,P as default}; diff --git a/assets/garden_representative-democracy_index.md.DuqwAFuu.lean.js b/assets/garden_representative-democracy_index.md.tqYsOBT9.js similarity index 96% rename from assets/garden_representative-democracy_index.md.DuqwAFuu.lean.js rename to assets/garden_representative-democracy_index.md.tqYsOBT9.js index f2df78000..a458e39c0 100644 --- a/assets/garden_representative-democracy_index.md.DuqwAFuu.lean.js +++ b/assets/garden_representative-democracy_index.md.tqYsOBT9.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as i,Q as e,K as t,u as a,p as o}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Representative Democracy",-1),l=["innerHTML"],p=e("hr",null,null,-1),d=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/anarchism/index.md"},"Anarchism"),e("a",{href:"/garden/political-quizzes/index.md"},"Political Quizzes")],-1),m=e("p",null,[t("A form of democracy where people vote for representatives who then vote on the actual issues. The US has a representative democracy. By virtue of representatives not perfectly reflecting the views of their constituents, and by forming a hierarchy of power, this is a form of Democracy that is not "),e("a",{href:"/garden/anarchism/"},"Anarchistic"),t(".")],-1),h=e("p",null,"Representative forms of government were once useful for their logistical simplifications, but now primarily serve as a way to limit the range of acceptable political opinions/options and to perpetuate the reign of those in power.",-1),w=JSON.parse('{"title":"Representative Democracy","description":"","frontmatter":{"public":"true","slug":"representative-democracy","title":"Representative Democracy","prev":false,"next":false},"headers":[],"relativePath":"garden/representative-democracy/index.md","filePath":"garden/representative-democracy/index.md"}'),u={name:"garden/representative-democracy/index.md"},x=Object.assign(u,{setup(f){const r=s();return(_,v)=>(o(),i("div",null,[c,e("p",null,[t("87 words, ~0 minute read. "),e("span",{innerHTML:a(n)[`site/${a(r).page.value.relativePath}`]},null,8,l)]),p,d,m,h]))}});export{w as __pageData,x as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as i,Q as e,K as t,u as a,p as o}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Representative Democracy",-1),l=["innerHTML"],p=e("hr",null,null,-1),d=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/anarchism/index.md"},"Anarchism"),e("a",{href:"/garden/political-quizzes/index.md"},"Political Quizzes")],-1),m=e("p",null,[t("A form of democracy where people vote for representatives who then vote on the actual issues. The US has a representative democracy. By virtue of representatives not perfectly reflecting the views of their constituents, and by forming a hierarchy of power, this is a form of Democracy that is not "),e("a",{href:"/garden/anarchism/"},"Anarchistic"),t(".")],-1),h=e("p",null,"Representative forms of government were once useful for their logistical simplifications, but now primarily serve as a way to limit the range of acceptable political opinions/options and to perpetuate the reign of those in power.",-1),w=JSON.parse('{"title":"Representative Democracy","description":"","frontmatter":{"public":"true","slug":"representative-democracy","title":"Representative Democracy","prev":false,"next":false},"headers":[],"relativePath":"garden/representative-democracy/index.md","filePath":"garden/representative-democracy/index.md"}'),u={name:"garden/representative-democracy/index.md"},x=Object.assign(u,{setup(f){const r=s();return(_,v)=>(o(),i("div",null,[c,e("p",null,[t("87 words, ~0 minute read. "),e("span",{innerHTML:a(n)[`site/${a(r).page.value.relativePath}`]},null,8,l)]),p,d,m,h]))}});export{w as __pageData,x as default}; diff --git a/assets/garden_representative-democracy_index.md.DuqwAFuu.js b/assets/garden_representative-democracy_index.md.tqYsOBT9.lean.js similarity index 96% rename from assets/garden_representative-democracy_index.md.DuqwAFuu.js rename to assets/garden_representative-democracy_index.md.tqYsOBT9.lean.js index f2df78000..a458e39c0 100644 --- a/assets/garden_representative-democracy_index.md.DuqwAFuu.js +++ b/assets/garden_representative-democracy_index.md.tqYsOBT9.lean.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as i,Q as e,K as t,u as a,p as o}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Representative Democracy",-1),l=["innerHTML"],p=e("hr",null,null,-1),d=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/anarchism/index.md"},"Anarchism"),e("a",{href:"/garden/political-quizzes/index.md"},"Political Quizzes")],-1),m=e("p",null,[t("A form of democracy where people vote for representatives who then vote on the actual issues. The US has a representative democracy. By virtue of representatives not perfectly reflecting the views of their constituents, and by forming a hierarchy of power, this is a form of Democracy that is not "),e("a",{href:"/garden/anarchism/"},"Anarchistic"),t(".")],-1),h=e("p",null,"Representative forms of government were once useful for their logistical simplifications, but now primarily serve as a way to limit the range of acceptable political opinions/options and to perpetuate the reign of those in power.",-1),w=JSON.parse('{"title":"Representative Democracy","description":"","frontmatter":{"public":"true","slug":"representative-democracy","title":"Representative Democracy","prev":false,"next":false},"headers":[],"relativePath":"garden/representative-democracy/index.md","filePath":"garden/representative-democracy/index.md"}'),u={name:"garden/representative-democracy/index.md"},x=Object.assign(u,{setup(f){const r=s();return(_,v)=>(o(),i("div",null,[c,e("p",null,[t("87 words, ~0 minute read. "),e("span",{innerHTML:a(n)[`site/${a(r).page.value.relativePath}`]},null,8,l)]),p,d,m,h]))}});export{w as __pageData,x as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as i,Q as e,K as t,u as a,p as o}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Representative Democracy",-1),l=["innerHTML"],p=e("hr",null,null,-1),d=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/anarchism/index.md"},"Anarchism"),e("a",{href:"/garden/political-quizzes/index.md"},"Political Quizzes")],-1),m=e("p",null,[t("A form of democracy where people vote for representatives who then vote on the actual issues. The US has a representative democracy. By virtue of representatives not perfectly reflecting the views of their constituents, and by forming a hierarchy of power, this is a form of Democracy that is not "),e("a",{href:"/garden/anarchism/"},"Anarchistic"),t(".")],-1),h=e("p",null,"Representative forms of government were once useful for their logistical simplifications, but now primarily serve as a way to limit the range of acceptable political opinions/options and to perpetuate the reign of those in power.",-1),w=JSON.parse('{"title":"Representative Democracy","description":"","frontmatter":{"public":"true","slug":"representative-democracy","title":"Representative Democracy","prev":false,"next":false},"headers":[],"relativePath":"garden/representative-democracy/index.md","filePath":"garden/representative-democracy/index.md"}'),u={name:"garden/representative-democracy/index.md"},x=Object.assign(u,{setup(f){const r=s();return(_,v)=>(o(),i("div",null,[c,e("p",null,[t("87 words, ~0 minute read. "),e("span",{innerHTML:a(n)[`site/${a(r).page.value.relativePath}`]},null,8,l)]),p,d,m,h]))}});export{w as __pageData,x as default}; diff --git a/assets/garden_scientific-constructivism_index.md.R4zVkePt.js b/assets/garden_scientific-constructivism_index.md.DBE0PQqI.js similarity index 98% rename from assets/garden_scientific-constructivism_index.md.R4zVkePt.js rename to assets/garden_scientific-constructivism_index.md.DBE0PQqI.js index 63cc35e66..cb79ff7f9 100644 --- a/assets/garden_scientific-constructivism_index.md.R4zVkePt.js +++ b/assets/garden_scientific-constructivism_index.md.DBE0PQqI.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as o,Q as e,K as r,u as t,ag as n,p as c}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Scientific Constructivism",-1),l=["innerHTML"],u=n('

Scientific constructivism is the philosophical idea that science is a Social Construct , in this case one created socially by scientists.

In her video on Social Constructs, Philosophy Tube discusses taxonomy as an example social construct. We observe animals' natural properties and form categories along arbitrary lines, and just deal with weird edge cases like the platypus that don't neatly fit into our prescribed lines. Some criticized this argument, because modern taxonomy typically looks at lineage and nearest shared ancestors, which avoids those edge cases and is therefore seen as a more "objective" measure. But us choosing to taxonomize using that metric versus any other is still inherently arbitrary and thus a construct.

This lovely response to Richard Dawkins claiming science is not a social construct is a great read. It argues, amongst other points, that science is to natural properties as a map is to the physical landscape. That is, science and maps are social constructs because they are our attempts to define and understand the underlying properties. Science is a process, not objective truth. (This same argument could be applied to mathematics, where there is some underlying property we don't have a name for, but mathematics - the axioms, theorems, proofs, etc. - as a collective body is a social construct above that underlying property). Philosophy Tube describes how height, one such natural property, might be used at different layers of social constructs. We have a concept of "tallness", which is a social construct based on the underlying property "height". However there could be a society that goes an extra layer of abstraction up and has a concept of "bigs", which are the elites of this society, as determined by their exceptional tallness. We might think its silly of such a society to structure themselves in this way, and question their reasoning for having a concept of "bigs" in the first place. But so to could a society that's one layer below ours question us for having a concept of "tallness", arguing that its fine to measure height but that its silly to describe people as being tall or not. They might argue that they, by merely measuring a natural property of height, do not have a social construct. However a layer below even them might question them for choosing to measure height in the first place. Does that not inherently imbue meaning (and therefore a social definition) upon the measured number? And by that logic, any measured property, by us choosing to measure it in the first place, is some level of social construct.

Science will often be affected by our own biases and come to incorrect conclusions. A classic example of this is phrenology, a racist "science" that used its supposed " Objectivity" to argue for racial differences that didn't exist. You may argue that science has already built in affordances for previous research being determined incorrect, however. We have (flawed) peer reviews and regularly (ish) replicate experiments and further verify various historical theories. However even the process of peer reviews, the scientific method, and conducting science at all are social constructs. Academia similarly has arbitrary restrictions, like defining statistical significance at 5% difference, that arbitrarily determine what is science and what is not (and often leads to data dredging).

While looking online to see people who agree and disagree with science as a social construct, I found some interesting pages that didn't really fit in elsewhere. I found this paper, Questioning science: how knowledge is socially constructed , which has a cool sounding abstract but I haven't found the article itself, and considering how little its been cited it seems far from seminal. I also found this entertaining forum thread discussing social constructs and science, which became a good example of how many people believe something being a construct means its not "real", and that therefore anything real/observable must therefore not be a construct. Fortunately, there are some voices in there attempting to clarify the nature of social constructs, and the back and forth was just enjoyable to read.

',6),b=JSON.parse('{"title":"Scientific Constructivism","description":"","frontmatter":{"public":"true","slug":"scientific-constructivism","title":"Scientific Constructivism","prev":false,"next":false},"headers":[],"relativePath":"garden/scientific-constructivism/index.md","filePath":"garden/scientific-constructivism/index.md"}'),d={name:"garden/scientific-constructivism/index.md"},v=Object.assign(d,{setup(p){const a=s();return(f,m)=>(c(),o("div",null,[h,e("p",null,[r("271 words, ~1 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,l)]),u]))}});export{b as __pageData,v as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as o,Q as e,K as r,u as t,ag as n,p as c}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Scientific Constructivism",-1),l=["innerHTML"],u=n('

Scientific constructivism is the philosophical idea that science is a Social Construct , in this case one created socially by scientists.

In her video on Social Constructs, Philosophy Tube discusses taxonomy as an example social construct. We observe animals' natural properties and form categories along arbitrary lines, and just deal with weird edge cases like the platypus that don't neatly fit into our prescribed lines. Some criticized this argument, because modern taxonomy typically looks at lineage and nearest shared ancestors, which avoids those edge cases and is therefore seen as a more "objective" measure. But us choosing to taxonomize using that metric versus any other is still inherently arbitrary and thus a construct.

This lovely response to Richard Dawkins claiming science is not a social construct is a great read. It argues, amongst other points, that science is to natural properties as a map is to the physical landscape. That is, science and maps are social constructs because they are our attempts to define and understand the underlying properties. Science is a process, not objective truth. (This same argument could be applied to mathematics, where there is some underlying property we don't have a name for, but mathematics - the axioms, theorems, proofs, etc. - as a collective body is a social construct above that underlying property). Philosophy Tube describes how height, one such natural property, might be used at different layers of social constructs. We have a concept of "tallness", which is a social construct based on the underlying property "height". However there could be a society that goes an extra layer of abstraction up and has a concept of "bigs", which are the elites of this society, as determined by their exceptional tallness. We might think its silly of such a society to structure themselves in this way, and question their reasoning for having a concept of "bigs" in the first place. But so to could a society that's one layer below ours question us for having a concept of "tallness", arguing that its fine to measure height but that its silly to describe people as being tall or not. They might argue that they, by merely measuring a natural property of height, do not have a social construct. However a layer below even them might question them for choosing to measure height in the first place. Does that not inherently imbue meaning (and therefore a social definition) upon the measured number? And by that logic, any measured property, by us choosing to measure it in the first place, is some level of social construct.

Science will often be affected by our own biases and come to incorrect conclusions. A classic example of this is phrenology, a racist "science" that used its supposed " Objectivity" to argue for racial differences that didn't exist. You may argue that science has already built in affordances for previous research being determined incorrect, however. We have (flawed) peer reviews and regularly (ish) replicate experiments and further verify various historical theories. However even the process of peer reviews, the scientific method, and conducting science at all are social constructs. Academia similarly has arbitrary restrictions, like defining statistical significance at 5% difference, that arbitrarily determine what is science and what is not (and often leads to data dredging).

While looking online to see people who agree and disagree with science as a social construct, I found some interesting pages that didn't really fit in elsewhere. I found this paper, Questioning science: how knowledge is socially constructed , which has a cool sounding abstract but I haven't found the article itself, and considering how little its been cited it seems far from seminal. I also found this entertaining forum thread discussing social constructs and science, which became a good example of how many people believe something being a construct means its not "real", and that therefore anything real/observable must therefore not be a construct. Fortunately, there are some voices in there attempting to clarify the nature of social constructs, and the back and forth was just enjoyable to read.

',6),b=JSON.parse('{"title":"Scientific Constructivism","description":"","frontmatter":{"public":"true","slug":"scientific-constructivism","title":"Scientific Constructivism","prev":false,"next":false},"headers":[],"relativePath":"garden/scientific-constructivism/index.md","filePath":"garden/scientific-constructivism/index.md"}'),d={name:"garden/scientific-constructivism/index.md"},v=Object.assign(d,{setup(p){const a=s();return(f,m)=>(c(),o("div",null,[h,e("p",null,[r("271 words, ~1 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,l)]),u]))}});export{b as __pageData,v as default}; diff --git a/assets/garden_scientific-constructivism_index.md.R4zVkePt.lean.js b/assets/garden_scientific-constructivism_index.md.DBE0PQqI.lean.js similarity index 92% rename from assets/garden_scientific-constructivism_index.md.R4zVkePt.lean.js rename to assets/garden_scientific-constructivism_index.md.DBE0PQqI.lean.js index 4b105d8f8..566ad8bf3 100644 --- a/assets/garden_scientific-constructivism_index.md.R4zVkePt.lean.js +++ b/assets/garden_scientific-constructivism_index.md.DBE0PQqI.lean.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as o,Q as e,K as r,u as t,ag as n,p as c}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Scientific Constructivism",-1),l=["innerHTML"],u=n("",6),b=JSON.parse('{"title":"Scientific Constructivism","description":"","frontmatter":{"public":"true","slug":"scientific-constructivism","title":"Scientific Constructivism","prev":false,"next":false},"headers":[],"relativePath":"garden/scientific-constructivism/index.md","filePath":"garden/scientific-constructivism/index.md"}'),d={name:"garden/scientific-constructivism/index.md"},v=Object.assign(d,{setup(p){const a=s();return(f,m)=>(c(),o("div",null,[h,e("p",null,[r("271 words, ~1 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,l)]),u]))}});export{b as __pageData,v as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as o,Q as e,K as r,u as t,ag as n,p as c}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Scientific Constructivism",-1),l=["innerHTML"],u=n("",6),b=JSON.parse('{"title":"Scientific Constructivism","description":"","frontmatter":{"public":"true","slug":"scientific-constructivism","title":"Scientific Constructivism","prev":false,"next":false},"headers":[],"relativePath":"garden/scientific-constructivism/index.md","filePath":"garden/scientific-constructivism/index.md"}'),d={name:"garden/scientific-constructivism/index.md"},v=Object.assign(d,{setup(p){const a=s();return(f,m)=>(c(),o("div",null,[h,e("p",null,[r("271 words, ~1 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,l)]),u]))}});export{b as __pageData,v as default}; diff --git a/assets/garden_social-constructs_index.md.D9tB0zu2.js b/assets/garden_social-constructs_index.md.B2XU4IXD.js similarity index 99% rename from assets/garden_social-constructs_index.md.D9tB0zu2.js rename to assets/garden_social-constructs_index.md.B2XU4IXD.js index a4a3d2495..8bfb971d3 100644 --- a/assets/garden_social-constructs_index.md.D9tB0zu2.js +++ b/assets/garden_social-constructs_index.md.B2XU4IXD.js @@ -1 +1 @@ -import{M as s,q as a,Q as e,K as i,u as t,ag as n,p as r,aL as c}from"./chunks/framework.Sr2_9k8k.js";import{d as l}from"./chunks/git.data.D-Ga3RhB.js";const d=e("h1",{class:"p-name"},"Social Constructs",-1),u=["innerHTML"],h=n('
Referenced by:AnarchismGenderGerrymanderingGuide to Incrementals/Defining the GenreObjectivityPrescriptivism vs DescriptivismScientific ConstructivismTrans athletes in sports

Social constructs are concepts with social definitions. Having a "social definition" really just means its some concept or property some group of peoples (or even animals) has prescribed meaning to. You know of and use these all the time throughout your life, and have likely identified some common ones like gender or class. As we'll discuss, however, there are far, far many more social constructs than the ones commonly referred to as such. It should be noted that while these concepts are essentially "made up", in the sense that they are arbitrary distinctions created by imperfect beings, that does not make them "not real". They exist and are typically created for a reason, often convenience. However, those reasons can be analyzed and determined to be more harmful than useful. This article's goal is to discuss and encourage analyzing social constructs, to better identify them and determine their utility and impact on society. Furthermore that it's possible to change or even destroy these constructs, and it's our social duty to do so when appropriate.

With a definition for social constructs as a concept established, how would you go about defining a specific social construct? Well that's tricky, due to social constructs' nature. It's useful to define words using either Prescriptivism or Descriptivism, but social constructs are much too ephemeral and complex to truly be defined using either approach. How would you attempt to make a complete, non-simplified definition of gender, for example? Gender has an impact on all parts of society, with gender roles shaping our entire lives and society and it interacts with various other similarly complicated constructs like class or family. All of this makes these concepts so complex that many incredibly smart people will spend their entire lives just writing about a single construct. While useful, these papers are obviously not the way we are typically introduced to constructs, or how we gain an understanding of them within a complex network of constructs.

Kids effectively "learn" the definitions of social constructs via exposure to them. They don't need to be explicitly outlined, at least not wholly, but rather experienced and lived. Kids observe people performing their gender roles, recognize their family and duties within it, calculate their age by counting the number of birthdays they've had, etc. Humans are powerful at recognizing patterns and through that naturally build an understanding, piece by piece, for all these constructs and how they interact, even if they couldn't formally define any of them. They'll go on to follow the unstated rules of these constructs, reinforcing them and teaching them by demonstration to following generations.

These constructs form a complex web, where any specific construct is only useful in the context of the web it is both a part of and dependent on. For example, knowing what a "bakery" is depends on the concept of a store, which depends on the concept of a building, and which depends on the concept of a structure. And this is just one path we could've taken - we could've alternatively explored bread or employees or shopping, and so on.

Ultimately, constructs are supposed to be useful. They allow us to communicate, understand, and exist within our society. One without any constructs would be impossible to do anything in. But these constructs also gained a lot of meanings during times of oppressive forces taking over the world, and can seriously harm people, particularly with concepts like Gender. In the same way these constructs allow us to understand the world around us, they can also mold us to fit those definitions. That's my real motive behind this page - to help recognize these constructs, analyze their utility, and ultimately decide if they're a construct worth continued support.

Some social constructs may seem to have straightforward definitions, but there is nuance and caveats that are still exclusively defined through social means. Take soup, for example. Oxford describes it as "a liquid dish, typically made by boiling meat, fish, or vegetables, etc. in stock or water". Well first off, that "typically" is already a concession that there are some traits that seem common, but not necessary to the definition. Is a bowl of cereal and milk considered soup? How liquid does the base have to be - would spaghetti Os count? And perhaps even a "liquid dish" is a murky requirement itself; let's talk about a game called Something something soup something, which uses gameplay of deciding which of various weird maybe-soups actually counts as soup. Their goal is to reveal through gameplay that "that even an ordinary concept like 'soup' is vague, shifting, impossible to define exhaustively". They released an analysis of results from what people typically considered requirements for "soupyness", and found nearly a third of participants (from focus groups and tracked players) accepted solids like rocks or ice cubes as viable bases for a soup. The oxford definition didn't mention container or utensil used for consuming soup, but the game found 25% of their focus group and 10% of their players considered the container being bowl-like or the utensil spoon-like as important. The point is that these definitions are subjective and learned socially, and thus have blurred edges that can change over time - you won't be able to find a complete definition in any dictionary. And don't even get me started on what a sandwich is!

Similar to how social constructs can have a nice simple definition that doesn't really encapsulate the social definition, the definition of social constructs as "concepts with social definitions" doesn't really explain just how ubiquitous these concepts are . Nearly everything is a social construct; everything from "age" to "bakeries" to "north" to "sandwiches" are social constructs; These concepts that society has built an understanding of over long periods of time, and have been shaped by our shared cultures and values. Even naming those constructs was a social agreement that those concepts are worth pointing out - Why make distinctions between different types of stores? Why distinguish some buildings as stores in the first place? Or call some structures buildings and others, like a fence, not? All of these are social constructs we use to help understand the world, that we learned through our experiences within our given society and culture. They're also all arbitrary and oftentimes you'll see these lines and distinctions differ between peoples. Take color, for example: We have many different colors - red, blue, green, yellow, purple, and so on. But why do we have those specific colors? Why does light red get its own name but not light green? Why is blue a boy color and pink a girl color? Is the dress black and blue or white and gold? Where is the line between dark blue and black? Why does the rainbow only sometimes include an indigo and violet? Well, all these decisions just kinda resolve as society continues to change. Those categories of colors just happened to be the ones our culture uses. But other cultures separate them out in different ways, like caring more about brightness than hue. Some cultures don't even have a concept of color, or might group colors differently than us - like grouping some colors as "like ripe fruit", which may seem just as out of place to us as us grouping green and tan in a category called "camo" would seem out of place to them.

',10),w=JSON.parse('{"title":"Social Constructs","description":"","frontmatter":{"alias":"Social Construct","public":"true","slug":"social-constructs","title":"Social Constructs","prev":false,"next":false},"headers":[],"relativePath":"garden/social-constructs/index.md","filePath":"garden/social-constructs/index.md"}'),p={name:"garden/social-constructs/index.md"},v=Object.assign(p,{setup(m){const o=s();return(f,g)=>(r(),a("div",null,[d,e("p",null,[i("1088 words, ~6 minute read. "),e("span",{innerHTML:t(l)[`site/${t(o).page.value.relativePath}`]},null,8,u)]),h]))}});export{w as __pageData,v as default}; +import{M as s,q as a,Q as e,K as i,u as t,ag as n,p as r,aL as c}from"./chunks/framework.Sr2_9k8k.js";import{d as l}from"./chunks/git.data.BcrWSzMU.js";const d=e("h1",{class:"p-name"},"Social Constructs",-1),u=["innerHTML"],h=n('
Referenced by:AnarchismGenderGerrymanderingGuide to Incrementals/Defining the GenreObjectivityPrescriptivism vs DescriptivismScientific ConstructivismTrans athletes in sports

Social constructs are concepts with social definitions. Having a "social definition" really just means its some concept or property some group of peoples (or even animals) has prescribed meaning to. You know of and use these all the time throughout your life, and have likely identified some common ones like gender or class. As we'll discuss, however, there are far, far many more social constructs than the ones commonly referred to as such. It should be noted that while these concepts are essentially "made up", in the sense that they are arbitrary distinctions created by imperfect beings, that does not make them "not real". They exist and are typically created for a reason, often convenience. However, those reasons can be analyzed and determined to be more harmful than useful. This article's goal is to discuss and encourage analyzing social constructs, to better identify them and determine their utility and impact on society. Furthermore that it's possible to change or even destroy these constructs, and it's our social duty to do so when appropriate.

With a definition for social constructs as a concept established, how would you go about defining a specific social construct? Well that's tricky, due to social constructs' nature. It's useful to define words using either Prescriptivism or Descriptivism, but social constructs are much too ephemeral and complex to truly be defined using either approach. How would you attempt to make a complete, non-simplified definition of gender, for example? Gender has an impact on all parts of society, with gender roles shaping our entire lives and society and it interacts with various other similarly complicated constructs like class or family. All of this makes these concepts so complex that many incredibly smart people will spend their entire lives just writing about a single construct. While useful, these papers are obviously not the way we are typically introduced to constructs, or how we gain an understanding of them within a complex network of constructs.

Kids effectively "learn" the definitions of social constructs via exposure to them. They don't need to be explicitly outlined, at least not wholly, but rather experienced and lived. Kids observe people performing their gender roles, recognize their family and duties within it, calculate their age by counting the number of birthdays they've had, etc. Humans are powerful at recognizing patterns and through that naturally build an understanding, piece by piece, for all these constructs and how they interact, even if they couldn't formally define any of them. They'll go on to follow the unstated rules of these constructs, reinforcing them and teaching them by demonstration to following generations.

These constructs form a complex web, where any specific construct is only useful in the context of the web it is both a part of and dependent on. For example, knowing what a "bakery" is depends on the concept of a store, which depends on the concept of a building, and which depends on the concept of a structure. And this is just one path we could've taken - we could've alternatively explored bread or employees or shopping, and so on.

Ultimately, constructs are supposed to be useful. They allow us to communicate, understand, and exist within our society. One without any constructs would be impossible to do anything in. But these constructs also gained a lot of meanings during times of oppressive forces taking over the world, and can seriously harm people, particularly with concepts like Gender. In the same way these constructs allow us to understand the world around us, they can also mold us to fit those definitions. That's my real motive behind this page - to help recognize these constructs, analyze their utility, and ultimately decide if they're a construct worth continued support.

Some social constructs may seem to have straightforward definitions, but there is nuance and caveats that are still exclusively defined through social means. Take soup, for example. Oxford describes it as "a liquid dish, typically made by boiling meat, fish, or vegetables, etc. in stock or water". Well first off, that "typically" is already a concession that there are some traits that seem common, but not necessary to the definition. Is a bowl of cereal and milk considered soup? How liquid does the base have to be - would spaghetti Os count? And perhaps even a "liquid dish" is a murky requirement itself; let's talk about a game called Something something soup something, which uses gameplay of deciding which of various weird maybe-soups actually counts as soup. Their goal is to reveal through gameplay that "that even an ordinary concept like 'soup' is vague, shifting, impossible to define exhaustively". They released an analysis of results from what people typically considered requirements for "soupyness", and found nearly a third of participants (from focus groups and tracked players) accepted solids like rocks or ice cubes as viable bases for a soup. The oxford definition didn't mention container or utensil used for consuming soup, but the game found 25% of their focus group and 10% of their players considered the container being bowl-like or the utensil spoon-like as important. The point is that these definitions are subjective and learned socially, and thus have blurred edges that can change over time - you won't be able to find a complete definition in any dictionary. And don't even get me started on what a sandwich is!

Similar to how social constructs can have a nice simple definition that doesn't really encapsulate the social definition, the definition of social constructs as "concepts with social definitions" doesn't really explain just how ubiquitous these concepts are . Nearly everything is a social construct; everything from "age" to "bakeries" to "north" to "sandwiches" are social constructs; These concepts that society has built an understanding of over long periods of time, and have been shaped by our shared cultures and values. Even naming those constructs was a social agreement that those concepts are worth pointing out - Why make distinctions between different types of stores? Why distinguish some buildings as stores in the first place? Or call some structures buildings and others, like a fence, not? All of these are social constructs we use to help understand the world, that we learned through our experiences within our given society and culture. They're also all arbitrary and oftentimes you'll see these lines and distinctions differ between peoples. Take color, for example: We have many different colors - red, blue, green, yellow, purple, and so on. But why do we have those specific colors? Why does light red get its own name but not light green? Why is blue a boy color and pink a girl color? Is the dress black and blue or white and gold? Where is the line between dark blue and black? Why does the rainbow only sometimes include an indigo and violet? Well, all these decisions just kinda resolve as society continues to change. Those categories of colors just happened to be the ones our culture uses. But other cultures separate them out in different ways, like caring more about brightness than hue. Some cultures don't even have a concept of color, or might group colors differently than us - like grouping some colors as "like ripe fruit", which may seem just as out of place to us as us grouping green and tan in a category called "camo" would seem out of place to them.

',10),w=JSON.parse('{"title":"Social Constructs","description":"","frontmatter":{"alias":"Social Construct","public":"true","slug":"social-constructs","title":"Social Constructs","prev":false,"next":false},"headers":[],"relativePath":"garden/social-constructs/index.md","filePath":"garden/social-constructs/index.md"}'),p={name:"garden/social-constructs/index.md"},v=Object.assign(p,{setup(m){const o=s();return(f,g)=>(r(),a("div",null,[d,e("p",null,[i("1088 words, ~6 minute read. "),e("span",{innerHTML:t(l)[`site/${t(o).page.value.relativePath}`]},null,8,u)]),h]))}});export{w as __pageData,v as default}; diff --git a/assets/garden_social-constructs_index.md.D9tB0zu2.lean.js b/assets/garden_social-constructs_index.md.B2XU4IXD.lean.js similarity index 92% rename from assets/garden_social-constructs_index.md.D9tB0zu2.lean.js rename to assets/garden_social-constructs_index.md.B2XU4IXD.lean.js index fa0c65fd2..49629646f 100644 --- a/assets/garden_social-constructs_index.md.D9tB0zu2.lean.js +++ b/assets/garden_social-constructs_index.md.B2XU4IXD.lean.js @@ -1 +1 @@ -import{M as s,q as a,Q as e,K as i,u as t,ag as n,p as r,aL as c}from"./chunks/framework.Sr2_9k8k.js";import{d as l}from"./chunks/git.data.D-Ga3RhB.js";const d=e("h1",{class:"p-name"},"Social Constructs",-1),u=["innerHTML"],h=n("",10),w=JSON.parse('{"title":"Social Constructs","description":"","frontmatter":{"alias":"Social Construct","public":"true","slug":"social-constructs","title":"Social Constructs","prev":false,"next":false},"headers":[],"relativePath":"garden/social-constructs/index.md","filePath":"garden/social-constructs/index.md"}'),p={name:"garden/social-constructs/index.md"},v=Object.assign(p,{setup(m){const o=s();return(f,g)=>(r(),a("div",null,[d,e("p",null,[i("1088 words, ~6 minute read. "),e("span",{innerHTML:t(l)[`site/${t(o).page.value.relativePath}`]},null,8,u)]),h]))}});export{w as __pageData,v as default}; +import{M as s,q as a,Q as e,K as i,u as t,ag as n,p as r,aL as c}from"./chunks/framework.Sr2_9k8k.js";import{d as l}from"./chunks/git.data.BcrWSzMU.js";const d=e("h1",{class:"p-name"},"Social Constructs",-1),u=["innerHTML"],h=n("",10),w=JSON.parse('{"title":"Social Constructs","description":"","frontmatter":{"alias":"Social Construct","public":"true","slug":"social-constructs","title":"Social Constructs","prev":false,"next":false},"headers":[],"relativePath":"garden/social-constructs/index.md","filePath":"garden/social-constructs/index.md"}'),p={name:"garden/social-constructs/index.md"},v=Object.assign(p,{setup(m){const o=s();return(f,g)=>(r(),a("div",null,[d,e("p",null,[i("1088 words, ~6 minute read. "),e("span",{innerHTML:t(l)[`site/${t(o).page.value.relativePath}`]},null,8,u)]),h]))}});export{w as __pageData,v as default}; diff --git a/assets/garden_social-media_index.md.BaJiZhWB.js b/assets/garden_social-media_index.md.Dq5kAlQ5.js similarity index 97% rename from assets/garden_social-media_index.md.BaJiZhWB.js rename to assets/garden_social-media_index.md.Dq5kAlQ5.js index efbe4d313..c606ddbba 100644 --- a/assets/garden_social-media_index.md.BaJiZhWB.js +++ b/assets/garden_social-media_index.md.Dq5kAlQ5.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as n,Q as e,K as r,u as a,ag as d,p as s}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Social Media",-1),c=["innerHTML"],m=d('
Referenced by:CommuneDecentralized ModerationDecentralized Social MediaDigital LocalityFediverseFilter BubblesModeration

Social media is how we interact with people online. It's also increasingly becoming how we discover and discuss news and ideas. It's incredibly important, but flawed. A lot of pages in this digital garden criticize and attempt to solve these flaws.

Traditional social media is centralized, meaning you have to trust the central authority to be acting in your best interests. It also means you likely won't have control over the moderation rules, sorting methods, filters, or other aspects of the platform. Traditional social media is also overrun by entities trying to accumulate wealth in the "attention economy", meaning feeds are littered with influencers, advertisers, and scams. It's not a safe place to be and its not conducive to health conversations.

Federated Social Media is partially Decentralized, and includes services like Mastodon or Lemmy. These require self hosting, leading to it being a federation of smaller centralized authorities. Most people still won't have control over the platform, but may find a platform that's more tolerable to them. However, the process of doing so greatly increases the barrier of entry into the network, and stifles their adoption.

I personally advocate for a full decentralized social media, called the Agentic Fediverse . It should give full agency to the individual, and perhaps even introduce the concept of Digital Locality.

',6),v=JSON.parse('{"title":"Social Media","description":"","frontmatter":{"alias":"Social Web","public":"true","slug":"social-media","title":"Social Media","prev":false,"next":false},"headers":[],"relativePath":"garden/social-media/index.md","filePath":"garden/social-media/index.md"}'),h={name:"garden/social-media/index.md"},y=Object.assign(h,{setup(f){const t=o();return(u,p)=>(s(),n("div",null,[l,e("p",null,[r("222 words, ~1 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),m]))}});export{v as __pageData,y as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as n,Q as e,K as r,u as a,ag as d,p as s}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Social Media",-1),c=["innerHTML"],m=d('
Referenced by:CommuneDecentralized ModerationDecentralized Social MediaDigital LocalityFediverseFilter BubblesModeration

Social media is how we interact with people online. It's also increasingly becoming how we discover and discuss news and ideas. It's incredibly important, but flawed. A lot of pages in this digital garden criticize and attempt to solve these flaws.

Traditional social media is centralized, meaning you have to trust the central authority to be acting in your best interests. It also means you likely won't have control over the moderation rules, sorting methods, filters, or other aspects of the platform. Traditional social media is also overrun by entities trying to accumulate wealth in the "attention economy", meaning feeds are littered with influencers, advertisers, and scams. It's not a safe place to be and its not conducive to health conversations.

Federated Social Media is partially Decentralized, and includes services like Mastodon or Lemmy. These require self hosting, leading to it being a federation of smaller centralized authorities. Most people still won't have control over the platform, but may find a platform that's more tolerable to them. However, the process of doing so greatly increases the barrier of entry into the network, and stifles their adoption.

I personally advocate for a full decentralized social media, called the Agentic Fediverse . It should give full agency to the individual, and perhaps even introduce the concept of Digital Locality.

',6),v=JSON.parse('{"title":"Social Media","description":"","frontmatter":{"alias":"Social Web","public":"true","slug":"social-media","title":"Social Media","prev":false,"next":false},"headers":[],"relativePath":"garden/social-media/index.md","filePath":"garden/social-media/index.md"}'),h={name:"garden/social-media/index.md"},y=Object.assign(h,{setup(f){const t=o();return(u,p)=>(s(),n("div",null,[l,e("p",null,[r("222 words, ~1 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),m]))}});export{v as __pageData,y as default}; diff --git a/assets/garden_social-media_index.md.BaJiZhWB.lean.js b/assets/garden_social-media_index.md.Dq5kAlQ5.lean.js similarity index 91% rename from assets/garden_social-media_index.md.BaJiZhWB.lean.js rename to assets/garden_social-media_index.md.Dq5kAlQ5.lean.js index baed99096..07b770a64 100644 --- a/assets/garden_social-media_index.md.BaJiZhWB.lean.js +++ b/assets/garden_social-media_index.md.Dq5kAlQ5.lean.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as n,Q as e,K as r,u as a,ag as d,p as s}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Social Media",-1),c=["innerHTML"],m=d("",6),v=JSON.parse('{"title":"Social Media","description":"","frontmatter":{"alias":"Social Web","public":"true","slug":"social-media","title":"Social Media","prev":false,"next":false},"headers":[],"relativePath":"garden/social-media/index.md","filePath":"garden/social-media/index.md"}'),h={name:"garden/social-media/index.md"},y=Object.assign(h,{setup(f){const t=o();return(u,p)=>(s(),n("div",null,[l,e("p",null,[r("222 words, ~1 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),m]))}});export{v as __pageData,y as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as n,Q as e,K as r,u as a,ag as d,p as s}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Social Media",-1),c=["innerHTML"],m=d("",6),v=JSON.parse('{"title":"Social Media","description":"","frontmatter":{"alias":"Social Web","public":"true","slug":"social-media","title":"Social Media","prev":false,"next":false},"headers":[],"relativePath":"garden/social-media/index.md","filePath":"garden/social-media/index.md"}'),h={name:"garden/social-media/index.md"},y=Object.assign(h,{setup(f){const t=o();return(u,p)=>(s(),n("div",null,[l,e("p",null,[r("222 words, ~1 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),m]))}});export{v as __pageData,y as default}; diff --git a/assets/garden_synapse_index.md.BJZE3okQ.lean.js b/assets/garden_synapse_index.md.j2MWsuO_.js similarity index 94% rename from assets/garden_synapse_index.md.BJZE3okQ.lean.js rename to assets/garden_synapse_index.md.j2MWsuO_.js index d92a1d0bc..f4f960c32 100644 --- a/assets/garden_synapse_index.md.BJZE3okQ.lean.js +++ b/assets/garden_synapse_index.md.j2MWsuO_.js @@ -1 +1 @@ -import{d as s}from"./chunks/git.data.D-Ga3RhB.js";import{M as r,q as l,Q as e,K as a,u as n,p as o}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"Synapse",-1),d=["innerHTML"],p=e("hr",null,null,-1),c=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social")],-1),u=e("p",null,[e("a",{href:"https://github.com/element-hq/synapse",target:"_blank",rel:"noreferrer"},"Synapse"),a(" is an "),e("a",{href:"/garden/open-source/"},"Open Source"),a(" server software for the "),e("a",{href:"/garden/matrix/"},"Matrix"),a(" protocol")],-1),x=JSON.parse('{"title":"Synapse","description":"","frontmatter":{"public":"true","slug":"synapse","title":"Synapse","prev":false,"next":false},"headers":[],"relativePath":"garden/synapse/index.md","filePath":"garden/synapse/index.md"}'),_={name:"garden/synapse/index.md"},S=Object.assign(_,{setup(m){const t=r();return(h,f)=>(o(),l("div",null,[i,e("p",null,[a("2 words, ~0 minute read. "),e("span",{innerHTML:n(s)[`site/${n(t).page.value.relativePath}`]},null,8,d)]),p,c,u]))}});export{x as __pageData,S as default}; +import{d as s}from"./chunks/git.data.BcrWSzMU.js";import{M as r,q as l,Q as e,K as a,u as n,p as o}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"Synapse",-1),d=["innerHTML"],p=e("hr",null,null,-1),c=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social")],-1),u=e("p",null,[e("a",{href:"https://github.com/element-hq/synapse",target:"_blank",rel:"noreferrer"},"Synapse"),a(" is an "),e("a",{href:"/garden/open-source/"},"Open Source"),a(" server software for the "),e("a",{href:"/garden/matrix/"},"Matrix"),a(" protocol")],-1),x=JSON.parse('{"title":"Synapse","description":"","frontmatter":{"public":"true","slug":"synapse","title":"Synapse","prev":false,"next":false},"headers":[],"relativePath":"garden/synapse/index.md","filePath":"garden/synapse/index.md"}'),_={name:"garden/synapse/index.md"},S=Object.assign(_,{setup(m){const t=r();return(h,f)=>(o(),l("div",null,[i,e("p",null,[a("2 words, ~0 minute read. "),e("span",{innerHTML:n(s)[`site/${n(t).page.value.relativePath}`]},null,8,d)]),p,c,u]))}});export{x as __pageData,S as default}; diff --git a/assets/garden_synapse_index.md.BJZE3okQ.js b/assets/garden_synapse_index.md.j2MWsuO_.lean.js similarity index 94% rename from assets/garden_synapse_index.md.BJZE3okQ.js rename to assets/garden_synapse_index.md.j2MWsuO_.lean.js index d92a1d0bc..f4f960c32 100644 --- a/assets/garden_synapse_index.md.BJZE3okQ.js +++ b/assets/garden_synapse_index.md.j2MWsuO_.lean.js @@ -1 +1 @@ -import{d as s}from"./chunks/git.data.D-Ga3RhB.js";import{M as r,q as l,Q as e,K as a,u as n,p as o}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"Synapse",-1),d=["innerHTML"],p=e("hr",null,null,-1),c=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social")],-1),u=e("p",null,[e("a",{href:"https://github.com/element-hq/synapse",target:"_blank",rel:"noreferrer"},"Synapse"),a(" is an "),e("a",{href:"/garden/open-source/"},"Open Source"),a(" server software for the "),e("a",{href:"/garden/matrix/"},"Matrix"),a(" protocol")],-1),x=JSON.parse('{"title":"Synapse","description":"","frontmatter":{"public":"true","slug":"synapse","title":"Synapse","prev":false,"next":false},"headers":[],"relativePath":"garden/synapse/index.md","filePath":"garden/synapse/index.md"}'),_={name:"garden/synapse/index.md"},S=Object.assign(_,{setup(m){const t=r();return(h,f)=>(o(),l("div",null,[i,e("p",null,[a("2 words, ~0 minute read. "),e("span",{innerHTML:n(s)[`site/${n(t).page.value.relativePath}`]},null,8,d)]),p,c,u]))}});export{x as __pageData,S as default}; +import{d as s}from"./chunks/git.data.BcrWSzMU.js";import{M as r,q as l,Q as e,K as a,u as n,p as o}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"Synapse",-1),d=["innerHTML"],p=e("hr",null,null,-1),c=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social")],-1),u=e("p",null,[e("a",{href:"https://github.com/element-hq/synapse",target:"_blank",rel:"noreferrer"},"Synapse"),a(" is an "),e("a",{href:"/garden/open-source/"},"Open Source"),a(" server software for the "),e("a",{href:"/garden/matrix/"},"Matrix"),a(" protocol")],-1),x=JSON.parse('{"title":"Synapse","description":"","frontmatter":{"public":"true","slug":"synapse","title":"Synapse","prev":false,"next":false},"headers":[],"relativePath":"garden/synapse/index.md","filePath":"garden/synapse/index.md"}'),_={name:"garden/synapse/index.md"},S=Object.assign(_,{setup(m){const t=r();return(h,f)=>(o(),l("div",null,[i,e("p",null,[a("2 words, ~0 minute read. "),e("span",{innerHTML:n(s)[`site/${n(t).page.value.relativePath}`]},null,8,d)]),p,c,u]))}});export{x as __pageData,S as default}; diff --git a/assets/garden_technocracy_index.md.CtShObzY.js b/assets/garden_technocracy_index.md.CX0DwK9Y.js similarity index 97% rename from assets/garden_technocracy_index.md.CtShObzY.js rename to assets/garden_technocracy_index.md.CX0DwK9Y.js index d9b9cfbaa..0eace32eb 100644 --- a/assets/garden_technocracy_index.md.CtShObzY.js +++ b/assets/garden_technocracy_index.md.CX0DwK9Y.js @@ -1 +1 @@ -import{d as s}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as n,Q as e,K as t,u as a,p as r}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Technocracy",-1),l=["innerHTML"],h=e("hr",null,null,-1),d=e("p",null,[t(`Technocracies are a form of government where technical experts make the decisions. It sounds appealing and like a solution to the "problem" of "How can Democracy be good if most people are stupid?". Well I don't think that's really a problem in the first place, as it implies some sort of objective knowledge and truth, when really the best decision `),e("em",null,"is"),t(" the one those affected by the decision most agree with. However, even under the premise that tyranny of the majority is a problem worth addressing, technocracies don't hold up under critical analysis.")],-1),m=e("p",null,[t("Who decides the criteria for technical expertise? Whatever the answer is will be introducing bias into the government, because true meritocracies are a "),e("a",{href:"/garden/neoliberalism/"},"Neoliberal"),t(" myth. Indeed, this government would likely just perpetuate people's existing material conditions, as those with power will have access to more resources, which means they'll be more likely to be able to meet the qualifications of technical expertise and thus remain in power. Conversely, those in poorer material conditions will be less likely to become technical experts, and thus have less agency to improve their material conditions.")],-1),u=e("p",null,[t("In "),e("a",{href:"https://www.youtube.com/watch?v=4F9QzXjUB10",target:"_blank",rel:"noreferrer"},"TikTok Vs Democracy"),t(`, Abigail Thorne discusses how surveillance capitalism can lead to a technocracy-flavored version of authoritarianism, and argues that even if democracy is "not a system for choosing the best leader or guaranteeing the best outcome" that it is "a system that has maximal respect for everyone's equal humanity".`)],-1),p=e("p",null,"A similar implementation that's considered slightly more palatable is a democracy where those with more education get more votes. But this still has the same issues of who writes the criteria and perpetuating material conditions. That is, it makes the idea sound more palatable without meaningfully addressing any of the criticisms of technocracies.",-1),v=JSON.parse('{"title":"Technocracy","description":"","frontmatter":{"public":"true","slug":"technocracy","title":"Technocracy","prev":false,"next":false},"headers":[],"relativePath":"garden/technocracy/index.md","filePath":"garden/technocracy/index.md"}'),f={name:"garden/technocracy/index.md"},k=Object.assign(f,{setup(y){const o=i();return(g,w)=>(r(),n("div",null,[c,e("p",null,[t("296 words, ~2 minute read. "),e("span",{innerHTML:a(s)[`site/${a(o).page.value.relativePath}`]},null,8,l)]),h,d,m,u,p]))}});export{v as __pageData,k as default}; +import{d as s}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as n,Q as e,K as t,u as a,p as r}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Technocracy",-1),l=["innerHTML"],h=e("hr",null,null,-1),d=e("p",null,[t(`Technocracies are a form of government where technical experts make the decisions. It sounds appealing and like a solution to the "problem" of "How can Democracy be good if most people are stupid?". Well I don't think that's really a problem in the first place, as it implies some sort of objective knowledge and truth, when really the best decision `),e("em",null,"is"),t(" the one those affected by the decision most agree with. However, even under the premise that tyranny of the majority is a problem worth addressing, technocracies don't hold up under critical analysis.")],-1),m=e("p",null,[t("Who decides the criteria for technical expertise? Whatever the answer is will be introducing bias into the government, because true meritocracies are a "),e("a",{href:"/garden/neoliberalism/"},"Neoliberal"),t(" myth. Indeed, this government would likely just perpetuate people's existing material conditions, as those with power will have access to more resources, which means they'll be more likely to be able to meet the qualifications of technical expertise and thus remain in power. Conversely, those in poorer material conditions will be less likely to become technical experts, and thus have less agency to improve their material conditions.")],-1),u=e("p",null,[t("In "),e("a",{href:"https://www.youtube.com/watch?v=4F9QzXjUB10",target:"_blank",rel:"noreferrer"},"TikTok Vs Democracy"),t(`, Abigail Thorne discusses how surveillance capitalism can lead to a technocracy-flavored version of authoritarianism, and argues that even if democracy is "not a system for choosing the best leader or guaranteeing the best outcome" that it is "a system that has maximal respect for everyone's equal humanity".`)],-1),p=e("p",null,"A similar implementation that's considered slightly more palatable is a democracy where those with more education get more votes. But this still has the same issues of who writes the criteria and perpetuating material conditions. That is, it makes the idea sound more palatable without meaningfully addressing any of the criticisms of technocracies.",-1),v=JSON.parse('{"title":"Technocracy","description":"","frontmatter":{"public":"true","slug":"technocracy","title":"Technocracy","prev":false,"next":false},"headers":[],"relativePath":"garden/technocracy/index.md","filePath":"garden/technocracy/index.md"}'),f={name:"garden/technocracy/index.md"},k=Object.assign(f,{setup(y){const o=i();return(g,w)=>(r(),n("div",null,[c,e("p",null,[t("296 words, ~2 minute read. "),e("span",{innerHTML:a(s)[`site/${a(o).page.value.relativePath}`]},null,8,l)]),h,d,m,u,p]))}});export{v as __pageData,k as default}; diff --git a/assets/garden_technocracy_index.md.CtShObzY.lean.js b/assets/garden_technocracy_index.md.CX0DwK9Y.lean.js similarity index 97% rename from assets/garden_technocracy_index.md.CtShObzY.lean.js rename to assets/garden_technocracy_index.md.CX0DwK9Y.lean.js index d9b9cfbaa..0eace32eb 100644 --- a/assets/garden_technocracy_index.md.CtShObzY.lean.js +++ b/assets/garden_technocracy_index.md.CX0DwK9Y.lean.js @@ -1 +1 @@ -import{d as s}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as n,Q as e,K as t,u as a,p as r}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Technocracy",-1),l=["innerHTML"],h=e("hr",null,null,-1),d=e("p",null,[t(`Technocracies are a form of government where technical experts make the decisions. It sounds appealing and like a solution to the "problem" of "How can Democracy be good if most people are stupid?". Well I don't think that's really a problem in the first place, as it implies some sort of objective knowledge and truth, when really the best decision `),e("em",null,"is"),t(" the one those affected by the decision most agree with. However, even under the premise that tyranny of the majority is a problem worth addressing, technocracies don't hold up under critical analysis.")],-1),m=e("p",null,[t("Who decides the criteria for technical expertise? Whatever the answer is will be introducing bias into the government, because true meritocracies are a "),e("a",{href:"/garden/neoliberalism/"},"Neoliberal"),t(" myth. Indeed, this government would likely just perpetuate people's existing material conditions, as those with power will have access to more resources, which means they'll be more likely to be able to meet the qualifications of technical expertise and thus remain in power. Conversely, those in poorer material conditions will be less likely to become technical experts, and thus have less agency to improve their material conditions.")],-1),u=e("p",null,[t("In "),e("a",{href:"https://www.youtube.com/watch?v=4F9QzXjUB10",target:"_blank",rel:"noreferrer"},"TikTok Vs Democracy"),t(`, Abigail Thorne discusses how surveillance capitalism can lead to a technocracy-flavored version of authoritarianism, and argues that even if democracy is "not a system for choosing the best leader or guaranteeing the best outcome" that it is "a system that has maximal respect for everyone's equal humanity".`)],-1),p=e("p",null,"A similar implementation that's considered slightly more palatable is a democracy where those with more education get more votes. But this still has the same issues of who writes the criteria and perpetuating material conditions. That is, it makes the idea sound more palatable without meaningfully addressing any of the criticisms of technocracies.",-1),v=JSON.parse('{"title":"Technocracy","description":"","frontmatter":{"public":"true","slug":"technocracy","title":"Technocracy","prev":false,"next":false},"headers":[],"relativePath":"garden/technocracy/index.md","filePath":"garden/technocracy/index.md"}'),f={name:"garden/technocracy/index.md"},k=Object.assign(f,{setup(y){const o=i();return(g,w)=>(r(),n("div",null,[c,e("p",null,[t("296 words, ~2 minute read. "),e("span",{innerHTML:a(s)[`site/${a(o).page.value.relativePath}`]},null,8,l)]),h,d,m,u,p]))}});export{v as __pageData,k as default}; +import{d as s}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as n,Q as e,K as t,u as a,p as r}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Technocracy",-1),l=["innerHTML"],h=e("hr",null,null,-1),d=e("p",null,[t(`Technocracies are a form of government where technical experts make the decisions. It sounds appealing and like a solution to the "problem" of "How can Democracy be good if most people are stupid?". Well I don't think that's really a problem in the first place, as it implies some sort of objective knowledge and truth, when really the best decision `),e("em",null,"is"),t(" the one those affected by the decision most agree with. However, even under the premise that tyranny of the majority is a problem worth addressing, technocracies don't hold up under critical analysis.")],-1),m=e("p",null,[t("Who decides the criteria for technical expertise? Whatever the answer is will be introducing bias into the government, because true meritocracies are a "),e("a",{href:"/garden/neoliberalism/"},"Neoliberal"),t(" myth. Indeed, this government would likely just perpetuate people's existing material conditions, as those with power will have access to more resources, which means they'll be more likely to be able to meet the qualifications of technical expertise and thus remain in power. Conversely, those in poorer material conditions will be less likely to become technical experts, and thus have less agency to improve their material conditions.")],-1),u=e("p",null,[t("In "),e("a",{href:"https://www.youtube.com/watch?v=4F9QzXjUB10",target:"_blank",rel:"noreferrer"},"TikTok Vs Democracy"),t(`, Abigail Thorne discusses how surveillance capitalism can lead to a technocracy-flavored version of authoritarianism, and argues that even if democracy is "not a system for choosing the best leader or guaranteeing the best outcome" that it is "a system that has maximal respect for everyone's equal humanity".`)],-1),p=e("p",null,"A similar implementation that's considered slightly more palatable is a democracy where those with more education get more votes. But this still has the same issues of who writes the criteria and perpetuating material conditions. That is, it makes the idea sound more palatable without meaningfully addressing any of the criticisms of technocracies.",-1),v=JSON.parse('{"title":"Technocracy","description":"","frontmatter":{"public":"true","slug":"technocracy","title":"Technocracy","prev":false,"next":false},"headers":[],"relativePath":"garden/technocracy/index.md","filePath":"garden/technocracy/index.md"}'),f={name:"garden/technocracy/index.md"},k=Object.assign(f,{setup(y){const o=i();return(g,w)=>(r(),n("div",null,[c,e("p",null,[t("296 words, ~2 minute read. "),e("span",{innerHTML:a(s)[`site/${a(o).page.value.relativePath}`]},null,8,l)]),h,d,m,u,p]))}});export{v as __pageData,k as default}; diff --git a/assets/garden_the-beginner-s-guide_index.md.k50dHl69.js b/assets/garden_the-beginner-s-guide_index.md.B9s_UlL-.js similarity index 97% rename from assets/garden_the-beginner-s-guide_index.md.k50dHl69.js rename to assets/garden_the-beginner-s-guide_index.md.B9s_UlL-.js index 4890023b6..4c76d5387 100644 --- a/assets/garden_the-beginner-s-guide_index.md.k50dHl69.js +++ b/assets/garden_the-beginner-s-guide_index.md.B9s_UlL-.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as i,Q as e,K as s,u as a,ag as o,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"The Beginner's Guide",-1),h=["innerHTML"],m=o('
Referenced by:Davey Wreden
Tags:Davey Wreden

My favorite video game of all time, bar none. Created by Davey Wreden

The game broadly comments on the relationship between creators and consumers, and it can apply to all forms of art

  • Perhaps also an important commentary on parasocial relationships

Important analyses:

',8),y=JSON.parse(`{"title":"The Beginner's Guide","description":"","frontmatter":{"public":"true","slug":"the-beginner-s-guide","tags":["Davey Wreden"],"title":"The Beginner's Guide","prev":false,"next":false},"headers":[],"relativePath":"garden/the-beginner-s-guide/index.md","filePath":"garden/the-beginner-s-guide/index.md"}`),u={name:"garden/the-beginner-s-guide/index.md"},b=Object.assign(u,{setup(p){const r=n();return(g,c)=>(l(),i("div",null,[d,e("p",null,[s("144 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,h)]),m]))}});export{y as __pageData,b as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as i,Q as e,K as s,u as a,ag as o,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"The Beginner's Guide",-1),h=["innerHTML"],m=o('
Referenced by:Davey Wreden
Tags:Davey Wreden

My favorite video game of all time, bar none. Created by Davey Wreden

The game broadly comments on the relationship between creators and consumers, and it can apply to all forms of art

  • Perhaps also an important commentary on parasocial relationships

Important analyses:

',8),y=JSON.parse(`{"title":"The Beginner's Guide","description":"","frontmatter":{"public":"true","slug":"the-beginner-s-guide","tags":["Davey Wreden"],"title":"The Beginner's Guide","prev":false,"next":false},"headers":[],"relativePath":"garden/the-beginner-s-guide/index.md","filePath":"garden/the-beginner-s-guide/index.md"}`),u={name:"garden/the-beginner-s-guide/index.md"},b=Object.assign(u,{setup(p){const r=n();return(g,c)=>(l(),i("div",null,[d,e("p",null,[s("144 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,h)]),m]))}});export{y as __pageData,b as default}; diff --git a/assets/garden_the-beginner-s-guide_index.md.k50dHl69.lean.js b/assets/garden_the-beginner-s-guide_index.md.B9s_UlL-.lean.js similarity index 92% rename from assets/garden_the-beginner-s-guide_index.md.k50dHl69.lean.js rename to assets/garden_the-beginner-s-guide_index.md.B9s_UlL-.lean.js index e6f9d81c1..313637c2d 100644 --- a/assets/garden_the-beginner-s-guide_index.md.k50dHl69.lean.js +++ b/assets/garden_the-beginner-s-guide_index.md.B9s_UlL-.lean.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as i,Q as e,K as s,u as a,ag as o,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"The Beginner's Guide",-1),h=["innerHTML"],m=o("",8),y=JSON.parse(`{"title":"The Beginner's Guide","description":"","frontmatter":{"public":"true","slug":"the-beginner-s-guide","tags":["Davey Wreden"],"title":"The Beginner's Guide","prev":false,"next":false},"headers":[],"relativePath":"garden/the-beginner-s-guide/index.md","filePath":"garden/the-beginner-s-guide/index.md"}`),u={name:"garden/the-beginner-s-guide/index.md"},b=Object.assign(u,{setup(p){const r=n();return(g,c)=>(l(),i("div",null,[d,e("p",null,[s("144 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,h)]),m]))}});export{y as __pageData,b as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as i,Q as e,K as s,u as a,ag as o,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"The Beginner's Guide",-1),h=["innerHTML"],m=o("",8),y=JSON.parse(`{"title":"The Beginner's Guide","description":"","frontmatter":{"public":"true","slug":"the-beginner-s-guide","tags":["Davey Wreden"],"title":"The Beginner's Guide","prev":false,"next":false},"headers":[],"relativePath":"garden/the-beginner-s-guide/index.md","filePath":"garden/the-beginner-s-guide/index.md"}`),u={name:"garden/the-beginner-s-guide/index.md"},b=Object.assign(u,{setup(p){const r=n();return(g,c)=>(l(),i("div",null,[d,e("p",null,[s("144 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,h)]),m]))}});export{y as __pageData,b as default}; diff --git a/assets/garden_the-cozy-web_index.md.D01M1HnW.js b/assets/garden_the-cozy-web_index.md.DaheNEdp.js similarity index 95% rename from assets/garden_the-cozy-web_index.md.D01M1HnW.js rename to assets/garden_the-cozy-web_index.md.DaheNEdp.js index 119cceaae..72fa5c1ff 100644 --- a/assets/garden_the-cozy-web_index.md.D01M1HnW.js +++ b/assets/garden_the-cozy-web_index.md.DaheNEdp.js @@ -1 +1 @@ -import{d as o}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as r,Q as e,K as t,u as a,p as l}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"The Cozy Web",-1),d=["innerHTML"],h=e("hr",null,null,-1),c=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/digital-gardens/index.md"},"Digital Gardens")],-1),p=e("p",null,"The Cozy Web is an extension of the dark forest theory of the Internet",-1),_=e("p",null,"It refers to the part of the web that is not web indexable",-1),u=e("p",null,"This part of the web is known for not typically having ads or marketers",-1),f=e("p",null,[t("Popularized by "),e("a",{href:"https://maggieappleton.com/cozy-web",target:"_blank",rel:"noreferrer"},"this article"),t(" written by Maggie Appleton, who has also written a lot about "),e("a",{href:"/garden/digital-gardens/"},"Digital Gardens")],-1),z=JSON.parse('{"title":"The Cozy Web","description":"","frontmatter":{"public":"true","slug":"the-cozy-web","title":"The Cozy Web","prev":false,"next":false},"headers":[],"relativePath":"garden/the-cozy-web/index.md","filePath":"garden/the-cozy-web/index.md"}'),g={name:"garden/the-cozy-web/index.md"},T=Object.assign(g,{setup(b){const n=s();return(m,y)=>(l(),r("div",null,[i,e("p",null,[t("45 words, ~0 minute read. "),e("span",{innerHTML:a(o)[`site/${a(n).page.value.relativePath}`]},null,8,d)]),h,c,p,_,u,f]))}});export{z as __pageData,T as default}; +import{d as o}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as r,Q as e,K as t,u as a,p as l}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"The Cozy Web",-1),d=["innerHTML"],h=e("hr",null,null,-1),c=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/digital-gardens/index.md"},"Digital Gardens")],-1),p=e("p",null,"The Cozy Web is an extension of the dark forest theory of the Internet",-1),_=e("p",null,"It refers to the part of the web that is not web indexable",-1),u=e("p",null,"This part of the web is known for not typically having ads or marketers",-1),f=e("p",null,[t("Popularized by "),e("a",{href:"https://maggieappleton.com/cozy-web",target:"_blank",rel:"noreferrer"},"this article"),t(" written by Maggie Appleton, who has also written a lot about "),e("a",{href:"/garden/digital-gardens/"},"Digital Gardens")],-1),z=JSON.parse('{"title":"The Cozy Web","description":"","frontmatter":{"public":"true","slug":"the-cozy-web","title":"The Cozy Web","prev":false,"next":false},"headers":[],"relativePath":"garden/the-cozy-web/index.md","filePath":"garden/the-cozy-web/index.md"}'),g={name:"garden/the-cozy-web/index.md"},T=Object.assign(g,{setup(b){const n=s();return(m,y)=>(l(),r("div",null,[i,e("p",null,[t("45 words, ~0 minute read. "),e("span",{innerHTML:a(o)[`site/${a(n).page.value.relativePath}`]},null,8,d)]),h,c,p,_,u,f]))}});export{z as __pageData,T as default}; diff --git a/assets/garden_the-cozy-web_index.md.D01M1HnW.lean.js b/assets/garden_the-cozy-web_index.md.DaheNEdp.lean.js similarity index 95% rename from assets/garden_the-cozy-web_index.md.D01M1HnW.lean.js rename to assets/garden_the-cozy-web_index.md.DaheNEdp.lean.js index 119cceaae..72fa5c1ff 100644 --- a/assets/garden_the-cozy-web_index.md.D01M1HnW.lean.js +++ b/assets/garden_the-cozy-web_index.md.DaheNEdp.lean.js @@ -1 +1 @@ -import{d as o}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as r,Q as e,K as t,u as a,p as l}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"The Cozy Web",-1),d=["innerHTML"],h=e("hr",null,null,-1),c=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/digital-gardens/index.md"},"Digital Gardens")],-1),p=e("p",null,"The Cozy Web is an extension of the dark forest theory of the Internet",-1),_=e("p",null,"It refers to the part of the web that is not web indexable",-1),u=e("p",null,"This part of the web is known for not typically having ads or marketers",-1),f=e("p",null,[t("Popularized by "),e("a",{href:"https://maggieappleton.com/cozy-web",target:"_blank",rel:"noreferrer"},"this article"),t(" written by Maggie Appleton, who has also written a lot about "),e("a",{href:"/garden/digital-gardens/"},"Digital Gardens")],-1),z=JSON.parse('{"title":"The Cozy Web","description":"","frontmatter":{"public":"true","slug":"the-cozy-web","title":"The Cozy Web","prev":false,"next":false},"headers":[],"relativePath":"garden/the-cozy-web/index.md","filePath":"garden/the-cozy-web/index.md"}'),g={name:"garden/the-cozy-web/index.md"},T=Object.assign(g,{setup(b){const n=s();return(m,y)=>(l(),r("div",null,[i,e("p",null,[t("45 words, ~0 minute read. "),e("span",{innerHTML:a(o)[`site/${a(n).page.value.relativePath}`]},null,8,d)]),h,c,p,_,u,f]))}});export{z as __pageData,T as default}; +import{d as o}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as r,Q as e,K as t,u as a,p as l}from"./chunks/framework.Sr2_9k8k.js";const i=e("h1",{class:"p-name"},"The Cozy Web",-1),d=["innerHTML"],h=e("hr",null,null,-1),c=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/digital-gardens/index.md"},"Digital Gardens")],-1),p=e("p",null,"The Cozy Web is an extension of the dark forest theory of the Internet",-1),_=e("p",null,"It refers to the part of the web that is not web indexable",-1),u=e("p",null,"This part of the web is known for not typically having ads or marketers",-1),f=e("p",null,[t("Popularized by "),e("a",{href:"https://maggieappleton.com/cozy-web",target:"_blank",rel:"noreferrer"},"this article"),t(" written by Maggie Appleton, who has also written a lot about "),e("a",{href:"/garden/digital-gardens/"},"Digital Gardens")],-1),z=JSON.parse('{"title":"The Cozy Web","description":"","frontmatter":{"public":"true","slug":"the-cozy-web","title":"The Cozy Web","prev":false,"next":false},"headers":[],"relativePath":"garden/the-cozy-web/index.md","filePath":"garden/the-cozy-web/index.md"}'),g={name:"garden/the-cozy-web/index.md"},T=Object.assign(g,{setup(b){const n=s();return(m,y)=>(l(),r("div",null,[i,e("p",null,[t("45 words, ~0 minute read. "),e("span",{innerHTML:a(o)[`site/${a(n).page.value.relativePath}`]},null,8,d)]),h,c,p,_,u,f]))}});export{z as __pageData,T as default}; diff --git a/assets/garden_the-indieweb_amplification_index.md.l9pwOcN0.js b/assets/garden_the-indieweb_amplification_index.md.3x5VqZ80.js similarity index 96% rename from assets/garden_the-indieweb_amplification_index.md.l9pwOcN0.js rename to assets/garden_the-indieweb_amplification_index.md.3x5VqZ80.js index de09764be..0d2453736 100644 --- a/assets/garden_the-indieweb_amplification_index.md.l9pwOcN0.js +++ b/assets/garden_the-indieweb_amplification_index.md.3x5VqZ80.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as o,Q as e,K as t,u as n,p as r}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"The IndieWeb/Amplification",-1),d=["innerHTML"],c=e("hr",null,null,-1),h=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social"),e("a",{href:"/garden/kronos/index.md"},"Kronos")],-1),m=e("p",null,"Refers to reblogging (and re-hosting, sometimes) of someone else's content on your own site",-1),u=e("p",null,[e("a",{href:"https://aramzs.xyz/essays/the-internet-is-a-series-of-webs/",target:"_blank",rel:"noreferrer"},"The Internet is a series of webs"),t(" discusses some ideas and best practices for amplification")],-1),p=e("p",null,[t("To ensure the rehosted content actually came from the claimed author and was not tampered with, all content should be signed using "),e("a",{href:"/garden/the-indieweb/signature-blocks/"},"The IndieWeb/Signature Blocks")],-1),T=JSON.parse('{"title":"The IndieWeb/Amplification","description":"","frontmatter":{"public":"true","slug":"the-indieweb/amplification","title":"The IndieWeb/Amplification","prev":false,"next":false},"headers":[],"relativePath":"garden/the-indieweb/amplification/index.md","filePath":"garden/the-indieweb/amplification/index.md"}'),f={name:"garden/the-indieweb/amplification/index.md"},k=Object.assign(f,{setup(_){const a=s();return(g,b)=>(r(),o("div",null,[l,e("p",null,[t("57 words, ~0 minute read. "),e("span",{innerHTML:n(i)[`site/${n(a).page.value.relativePath}`]},null,8,d)]),c,h,m,u,p]))}});export{T as __pageData,k as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as o,Q as e,K as t,u as n,p as r}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"The IndieWeb/Amplification",-1),d=["innerHTML"],c=e("hr",null,null,-1),h=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social"),e("a",{href:"/garden/kronos/index.md"},"Kronos")],-1),m=e("p",null,"Refers to reblogging (and re-hosting, sometimes) of someone else's content on your own site",-1),u=e("p",null,[e("a",{href:"https://aramzs.xyz/essays/the-internet-is-a-series-of-webs/",target:"_blank",rel:"noreferrer"},"The Internet is a series of webs"),t(" discusses some ideas and best practices for amplification")],-1),p=e("p",null,[t("To ensure the rehosted content actually came from the claimed author and was not tampered with, all content should be signed using "),e("a",{href:"/garden/the-indieweb/signature-blocks/"},"The IndieWeb/Signature Blocks")],-1),T=JSON.parse('{"title":"The IndieWeb/Amplification","description":"","frontmatter":{"public":"true","slug":"the-indieweb/amplification","title":"The IndieWeb/Amplification","prev":false,"next":false},"headers":[],"relativePath":"garden/the-indieweb/amplification/index.md","filePath":"garden/the-indieweb/amplification/index.md"}'),f={name:"garden/the-indieweb/amplification/index.md"},k=Object.assign(f,{setup(_){const a=s();return(g,b)=>(r(),o("div",null,[l,e("p",null,[t("57 words, ~0 minute read. "),e("span",{innerHTML:n(i)[`site/${n(a).page.value.relativePath}`]},null,8,d)]),c,h,m,u,p]))}});export{T as __pageData,k as default}; diff --git a/assets/garden_the-indieweb_amplification_index.md.l9pwOcN0.lean.js b/assets/garden_the-indieweb_amplification_index.md.3x5VqZ80.lean.js similarity index 96% rename from assets/garden_the-indieweb_amplification_index.md.l9pwOcN0.lean.js rename to assets/garden_the-indieweb_amplification_index.md.3x5VqZ80.lean.js index de09764be..0d2453736 100644 --- a/assets/garden_the-indieweb_amplification_index.md.l9pwOcN0.lean.js +++ b/assets/garden_the-indieweb_amplification_index.md.3x5VqZ80.lean.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as o,Q as e,K as t,u as n,p as r}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"The IndieWeb/Amplification",-1),d=["innerHTML"],c=e("hr",null,null,-1),h=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social"),e("a",{href:"/garden/kronos/index.md"},"Kronos")],-1),m=e("p",null,"Refers to reblogging (and re-hosting, sometimes) of someone else's content on your own site",-1),u=e("p",null,[e("a",{href:"https://aramzs.xyz/essays/the-internet-is-a-series-of-webs/",target:"_blank",rel:"noreferrer"},"The Internet is a series of webs"),t(" discusses some ideas and best practices for amplification")],-1),p=e("p",null,[t("To ensure the rehosted content actually came from the claimed author and was not tampered with, all content should be signed using "),e("a",{href:"/garden/the-indieweb/signature-blocks/"},"The IndieWeb/Signature Blocks")],-1),T=JSON.parse('{"title":"The IndieWeb/Amplification","description":"","frontmatter":{"public":"true","slug":"the-indieweb/amplification","title":"The IndieWeb/Amplification","prev":false,"next":false},"headers":[],"relativePath":"garden/the-indieweb/amplification/index.md","filePath":"garden/the-indieweb/amplification/index.md"}'),f={name:"garden/the-indieweb/amplification/index.md"},k=Object.assign(f,{setup(_){const a=s();return(g,b)=>(r(),o("div",null,[l,e("p",null,[t("57 words, ~0 minute read. "),e("span",{innerHTML:n(i)[`site/${n(a).page.value.relativePath}`]},null,8,d)]),c,h,m,u,p]))}});export{T as __pageData,k as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as o,Q as e,K as t,u as n,p as r}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"The IndieWeb/Amplification",-1),d=["innerHTML"],c=e("hr",null,null,-1),h=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social"),e("a",{href:"/garden/kronos/index.md"},"Kronos")],-1),m=e("p",null,"Refers to reblogging (and re-hosting, sometimes) of someone else's content on your own site",-1),u=e("p",null,[e("a",{href:"https://aramzs.xyz/essays/the-internet-is-a-series-of-webs/",target:"_blank",rel:"noreferrer"},"The Internet is a series of webs"),t(" discusses some ideas and best practices for amplification")],-1),p=e("p",null,[t("To ensure the rehosted content actually came from the claimed author and was not tampered with, all content should be signed using "),e("a",{href:"/garden/the-indieweb/signature-blocks/"},"The IndieWeb/Signature Blocks")],-1),T=JSON.parse('{"title":"The IndieWeb/Amplification","description":"","frontmatter":{"public":"true","slug":"the-indieweb/amplification","title":"The IndieWeb/Amplification","prev":false,"next":false},"headers":[],"relativePath":"garden/the-indieweb/amplification/index.md","filePath":"garden/the-indieweb/amplification/index.md"}'),f={name:"garden/the-indieweb/amplification/index.md"},k=Object.assign(f,{setup(_){const a=s();return(g,b)=>(r(),o("div",null,[l,e("p",null,[t("57 words, ~0 minute read. "),e("span",{innerHTML:n(i)[`site/${n(a).page.value.relativePath}`]},null,8,d)]),c,h,m,u,p]))}});export{T as __pageData,k as default}; diff --git a/assets/garden_the-indieweb_signature-blocks_index.md.BdHKJnLs.js b/assets/garden_the-indieweb_signature-blocks_index.md.C4-BOO4I.js similarity index 94% rename from assets/garden_the-indieweb_signature-blocks_index.md.BdHKJnLs.js rename to assets/garden_the-indieweb_signature-blocks_index.md.C4-BOO4I.js index 4c309e5d0..8883c9640 100644 --- a/assets/garden_the-indieweb_signature-blocks_index.md.BdHKJnLs.js +++ b/assets/garden_the-indieweb_signature-blocks_index.md.C4-BOO4I.js @@ -1 +1 @@ -import{d as s}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as r,Q as e,K as n,u as t,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"The IndieWeb/Signature Blocks",-1),d=["innerHTML"],c=e("hr",null,null,-1),u=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social"),e("a",{href:"/garden/kronos/index.md"},"Kronos")],-1),h=e("p",null,[n("A proposal I want to write for posting signed content on your "),e("a",{href:"/garden/the-small-web/"},"IndieWeb"),n(" website")],-1),k=JSON.parse('{"title":"The IndieWeb/Signature Blocks","description":"","frontmatter":{"public":"true","slug":"the-indieweb/signature-blocks","title":"The IndieWeb/Signature Blocks","prev":false,"next":false},"headers":[],"relativePath":"garden/the-indieweb/signature-blocks/index.md","filePath":"garden/the-indieweb/signature-blocks/index.md"}'),p={name:"garden/the-indieweb/signature-blocks/index.md"},w=Object.assign(p,{setup(_){const a=i();return(g,m)=>(o(),r("div",null,[l,e("p",null,[n("14 words, ~0 minute read. "),e("span",{innerHTML:t(s)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),c,u,h]))}});export{k as __pageData,w as default}; +import{d as s}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as r,Q as e,K as n,u as t,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"The IndieWeb/Signature Blocks",-1),d=["innerHTML"],c=e("hr",null,null,-1),u=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social"),e("a",{href:"/garden/kronos/index.md"},"Kronos")],-1),h=e("p",null,[n("A proposal I want to write for posting signed content on your "),e("a",{href:"/garden/the-small-web/"},"IndieWeb"),n(" website")],-1),k=JSON.parse('{"title":"The IndieWeb/Signature Blocks","description":"","frontmatter":{"public":"true","slug":"the-indieweb/signature-blocks","title":"The IndieWeb/Signature Blocks","prev":false,"next":false},"headers":[],"relativePath":"garden/the-indieweb/signature-blocks/index.md","filePath":"garden/the-indieweb/signature-blocks/index.md"}'),p={name:"garden/the-indieweb/signature-blocks/index.md"},w=Object.assign(p,{setup(_){const a=i();return(g,m)=>(o(),r("div",null,[l,e("p",null,[n("14 words, ~0 minute read. "),e("span",{innerHTML:t(s)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),c,u,h]))}});export{k as __pageData,w as default}; diff --git a/assets/garden_the-indieweb_signature-blocks_index.md.BdHKJnLs.lean.js b/assets/garden_the-indieweb_signature-blocks_index.md.C4-BOO4I.lean.js similarity index 94% rename from assets/garden_the-indieweb_signature-blocks_index.md.BdHKJnLs.lean.js rename to assets/garden_the-indieweb_signature-blocks_index.md.C4-BOO4I.lean.js index 4c309e5d0..8883c9640 100644 --- a/assets/garden_the-indieweb_signature-blocks_index.md.BdHKJnLs.lean.js +++ b/assets/garden_the-indieweb_signature-blocks_index.md.C4-BOO4I.lean.js @@ -1 +1 @@ -import{d as s}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as r,Q as e,K as n,u as t,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"The IndieWeb/Signature Blocks",-1),d=["innerHTML"],c=e("hr",null,null,-1),u=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social"),e("a",{href:"/garden/kronos/index.md"},"Kronos")],-1),h=e("p",null,[n("A proposal I want to write for posting signed content on your "),e("a",{href:"/garden/the-small-web/"},"IndieWeb"),n(" website")],-1),k=JSON.parse('{"title":"The IndieWeb/Signature Blocks","description":"","frontmatter":{"public":"true","slug":"the-indieweb/signature-blocks","title":"The IndieWeb/Signature Blocks","prev":false,"next":false},"headers":[],"relativePath":"garden/the-indieweb/signature-blocks/index.md","filePath":"garden/the-indieweb/signature-blocks/index.md"}'),p={name:"garden/the-indieweb/signature-blocks/index.md"},w=Object.assign(p,{setup(_){const a=i();return(g,m)=>(o(),r("div",null,[l,e("p",null,[n("14 words, ~0 minute read. "),e("span",{innerHTML:t(s)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),c,u,h]))}});export{k as __pageData,w as default}; +import{d as s}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as r,Q as e,K as n,u as t,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"The IndieWeb/Signature Blocks",-1),d=["innerHTML"],c=e("hr",null,null,-1),u=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/incremental-social/index.md"},"Incremental Social"),e("a",{href:"/garden/kronos/index.md"},"Kronos")],-1),h=e("p",null,[n("A proposal I want to write for posting signed content on your "),e("a",{href:"/garden/the-small-web/"},"IndieWeb"),n(" website")],-1),k=JSON.parse('{"title":"The IndieWeb/Signature Blocks","description":"","frontmatter":{"public":"true","slug":"the-indieweb/signature-blocks","title":"The IndieWeb/Signature Blocks","prev":false,"next":false},"headers":[],"relativePath":"garden/the-indieweb/signature-blocks/index.md","filePath":"garden/the-indieweb/signature-blocks/index.md"}'),p={name:"garden/the-indieweb/signature-blocks/index.md"},w=Object.assign(p,{setup(_){const a=i();return(g,m)=>(o(),r("div",null,[l,e("p",null,[n("14 words, ~0 minute read. "),e("span",{innerHTML:t(s)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),c,u,h]))}});export{k as __pageData,w as default}; diff --git a/assets/garden_the-small-web_index.md.Bkk1rEfe.js b/assets/garden_the-small-web_index.md.BHvDMKRi.js similarity index 99% rename from assets/garden_the-small-web_index.md.Bkk1rEfe.js rename to assets/garden_the-small-web_index.md.BHvDMKRi.js index 9ef094bfa..1ebe02722 100644 --- a/assets/garden_the-small-web_index.md.Bkk1rEfe.js +++ b/assets/garden_the-small-web_index.md.BHvDMKRi.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as o,Q as e,K as s,u as a,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"The Small Web",-1),d=["innerHTML"],b=n('
Referenced by:CommuneDecentralized IdentityDigital LocalityFedi v2My Personal WebsiteThe IndieWeb/Signature BlocksThis Knowledge HubWebringsWeird

The small web (also known as the indie web, personal web, the web revival movement, and other terms) refers to small, personal, independent websites. It is seen as a direct alternative to the centralized and homogenized websites like X, Meta, and TikTok. My Personal Website is part of the small web!

Motivation behind the small web

The modern web is bad

The small web is, at its roots, a direct response to the issues with the modern web:

The modern web is dominated by a handful of large websites, sometimes referred to as the "corporate web". These websites limit personalization, how you can use the website, and are filled with ads, marketers, and influencers.

The corporate web is designed for consuming content created by a few large/popular creators. This manifests in the near-ubiquitous infinitely scrolling feed of algorithmically chosen posts, optimized to keep you on the site for as long as possible, to the detriment of society.

Large websites, due to the profit motive, will naturally Enshittify.

The old web was good

In contrast to the above, the classic web was filled with many diverse sites that typically represented a single person or organization, who were able to fully tailor their site to what they wanted it to be. Websites would be more unique and interesting, since the creator would have full control over them. This also makes the whole web feel more personal and intimate, as you're looking at a closer representation of how someone chooses to portray themselves online, in a way a profile page on X or Meta cannot be.

There are still lessons we've learned over time that can apply to modern "small web" pages, like accessible design and how to be more inclusive.

The small web is anti-corporate

Small static websites are very cheap to host, making anti-features like ads unnecessary and therefore rare. In general small websites are cheap enough to avoid needing to think about monetization entirely, let alone worrying about how to perpetually make more money. This lack of profit motive behind most small websites contributes to a culture of not just being "not corporate", but "anti-corporate".

In general, the corporate web seems to have values that align with those of authoritarianism - control, surveillance, and hierarchy, whereas the small web aligns with anarchist values - autonomy, cooperation, and egalitarianism.

Further reading

These are videos and articles that continue expanding on the values and motivations behind the small web as an alternative to the corporate web:

Browsing the small web

Follow Webrings or other links from known small websites.

Marginalia is a search engine for non-commercial content with a "random" button and filters for the small web explicitly (amongst other useful filters!)

The Tildeverse contains a large set of personal websites.

  • Pick one of the member sites, and they'll have a list of all their users, who each have a custom page. Some may also list most recently updated pages, which is a good way of filtering out default pages.
  • You may also consider joining one of these communities. They're effectively shared Linux computers, with a focus on small tight knit communities as an alternative to social media. Great if you're interested in learning Linux and command line utilities!

Building personal websites

IndieWeb contains various information and resources on building personal websites that use open standards to better interact with readers and other sites consistently. Check out IndieWebify Me to get assistance implementing their standards.

Free hosting for static websites:

Other resources:

Streams

Microsub is a proposed protocol to support hosting streams of content on personal websites in a way they can be consistently ingested by microsub clients. This way, people could subscribe to multiple streams on independent websites and get them in one feed. Through this, the indie web becomes a Federated Social Media.

Streams also allow your personal website to be the one source of truth for your posted content, in a concept called POSSE - Publish (on your) Own Site, Syndicate Elsewhere (other social media sites). This would effectively solve the problems described in Hey Creators, Please Make Firehoses!

Multiple streams can be hosted by one site/person so people can subscribe to the kind of content they're interested in.

Digital Gardens

These sites may be useful to occasionally check up on rather than get notifications from on every post/change

  • Although Garden-RSS could allow those who want to receive notifications to do so

The future

The Internet is a series of webs talks about transitioning from our current consolidated web back to the indie web

',38),w=JSON.parse('{"title":"The Small Web","description":"","frontmatter":{"alias":"The IndieWeb, Personal Web, Personal Websites, IndieWeb","public":"true","slug":"the-small-web","title":"The Small Web","prev":false,"next":false},"headers":[],"relativePath":"garden/the-small-web/index.md","filePath":"garden/the-small-web/index.md"}'),c={name:"garden/the-small-web/index.md"},y=Object.assign(c,{setup(m){const t=i();return(u,p)=>(l(),o("div",null,[h,e("p",null,[s("731 words, ~4 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),b]))}});export{w as __pageData,y as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as o,Q as e,K as s,u as a,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"The Small Web",-1),d=["innerHTML"],b=n('
Referenced by:CommuneDecentralized IdentityDigital LocalityFedi v2My Personal WebsiteThe IndieWeb/Signature BlocksThis Knowledge HubWebringsWeird

The small web (also known as the indie web, personal web, the web revival movement, and other terms) refers to small, personal, independent websites. It is seen as a direct alternative to the centralized and homogenized websites like X, Meta, and TikTok. My Personal Website is part of the small web!

Motivation behind the small web

The modern web is bad

The small web is, at its roots, a direct response to the issues with the modern web:

The modern web is dominated by a handful of large websites, sometimes referred to as the "corporate web". These websites limit personalization, how you can use the website, and are filled with ads, marketers, and influencers.

The corporate web is designed for consuming content created by a few large/popular creators. This manifests in the near-ubiquitous infinitely scrolling feed of algorithmically chosen posts, optimized to keep you on the site for as long as possible, to the detriment of society.

Large websites, due to the profit motive, will naturally Enshittify.

The old web was good

In contrast to the above, the classic web was filled with many diverse sites that typically represented a single person or organization, who were able to fully tailor their site to what they wanted it to be. Websites would be more unique and interesting, since the creator would have full control over them. This also makes the whole web feel more personal and intimate, as you're looking at a closer representation of how someone chooses to portray themselves online, in a way a profile page on X or Meta cannot be.

There are still lessons we've learned over time that can apply to modern "small web" pages, like accessible design and how to be more inclusive.

The small web is anti-corporate

Small static websites are very cheap to host, making anti-features like ads unnecessary and therefore rare. In general small websites are cheap enough to avoid needing to think about monetization entirely, let alone worrying about how to perpetually make more money. This lack of profit motive behind most small websites contributes to a culture of not just being "not corporate", but "anti-corporate".

In general, the corporate web seems to have values that align with those of authoritarianism - control, surveillance, and hierarchy, whereas the small web aligns with anarchist values - autonomy, cooperation, and egalitarianism.

Further reading

These are videos and articles that continue expanding on the values and motivations behind the small web as an alternative to the corporate web:

Browsing the small web

Follow Webrings or other links from known small websites.

Marginalia is a search engine for non-commercial content with a "random" button and filters for the small web explicitly (amongst other useful filters!)

The Tildeverse contains a large set of personal websites.

  • Pick one of the member sites, and they'll have a list of all their users, who each have a custom page. Some may also list most recently updated pages, which is a good way of filtering out default pages.
  • You may also consider joining one of these communities. They're effectively shared Linux computers, with a focus on small tight knit communities as an alternative to social media. Great if you're interested in learning Linux and command line utilities!

Building personal websites

IndieWeb contains various information and resources on building personal websites that use open standards to better interact with readers and other sites consistently. Check out IndieWebify Me to get assistance implementing their standards.

Free hosting for static websites:

Other resources:

Streams

Microsub is a proposed protocol to support hosting streams of content on personal websites in a way they can be consistently ingested by microsub clients. This way, people could subscribe to multiple streams on independent websites and get them in one feed. Through this, the indie web becomes a Federated Social Media.

Streams also allow your personal website to be the one source of truth for your posted content, in a concept called POSSE - Publish (on your) Own Site, Syndicate Elsewhere (other social media sites). This would effectively solve the problems described in Hey Creators, Please Make Firehoses!

Multiple streams can be hosted by one site/person so people can subscribe to the kind of content they're interested in.

Digital Gardens

These sites may be useful to occasionally check up on rather than get notifications from on every post/change

  • Although Garden-RSS could allow those who want to receive notifications to do so

The future

The Internet is a series of webs talks about transitioning from our current consolidated web back to the indie web

',38),w=JSON.parse('{"title":"The Small Web","description":"","frontmatter":{"alias":"The IndieWeb, Personal Web, Personal Websites, IndieWeb","public":"true","slug":"the-small-web","title":"The Small Web","prev":false,"next":false},"headers":[],"relativePath":"garden/the-small-web/index.md","filePath":"garden/the-small-web/index.md"}'),c={name:"garden/the-small-web/index.md"},y=Object.assign(c,{setup(m){const t=i();return(u,p)=>(l(),o("div",null,[h,e("p",null,[s("731 words, ~4 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),b]))}});export{w as __pageData,y as default}; diff --git a/assets/garden_the-small-web_index.md.Bkk1rEfe.lean.js b/assets/garden_the-small-web_index.md.BHvDMKRi.lean.js similarity index 92% rename from assets/garden_the-small-web_index.md.Bkk1rEfe.lean.js rename to assets/garden_the-small-web_index.md.BHvDMKRi.lean.js index 19fdc8726..7bad03449 100644 --- a/assets/garden_the-small-web_index.md.Bkk1rEfe.lean.js +++ b/assets/garden_the-small-web_index.md.BHvDMKRi.lean.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as o,Q as e,K as s,u as a,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"The Small Web",-1),d=["innerHTML"],b=n("",38),w=JSON.parse('{"title":"The Small Web","description":"","frontmatter":{"alias":"The IndieWeb, Personal Web, Personal Websites, IndieWeb","public":"true","slug":"the-small-web","title":"The Small Web","prev":false,"next":false},"headers":[],"relativePath":"garden/the-small-web/index.md","filePath":"garden/the-small-web/index.md"}'),c={name:"garden/the-small-web/index.md"},y=Object.assign(c,{setup(m){const t=i();return(u,p)=>(l(),o("div",null,[h,e("p",null,[s("731 words, ~4 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),b]))}});export{w as __pageData,y as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as o,Q as e,K as s,u as a,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"The Small Web",-1),d=["innerHTML"],b=n("",38),w=JSON.parse('{"title":"The Small Web","description":"","frontmatter":{"alias":"The IndieWeb, Personal Web, Personal Websites, IndieWeb","public":"true","slug":"the-small-web","title":"The Small Web","prev":false,"next":false},"headers":[],"relativePath":"garden/the-small-web/index.md","filePath":"garden/the-small-web/index.md"}'),c={name:"garden/the-small-web/index.md"},y=Object.assign(c,{setup(m){const t=i();return(u,p)=>(l(),o("div",null,[h,e("p",null,[s("731 words, ~4 minute read. "),e("span",{innerHTML:a(r)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),b]))}});export{w as __pageData,y as default}; diff --git a/assets/garden_this-knowledge-hub_index.md.CLJqAHFR.js b/assets/garden_this-knowledge-hub_index.md.BAlSWWx9.js similarity index 97% rename from assets/garden_this-knowledge-hub_index.md.CLJqAHFR.js rename to assets/garden_this-knowledge-hub_index.md.BAlSWWx9.js index 48f27509c..03378f397 100644 --- a/assets/garden_this-knowledge-hub_index.md.CLJqAHFR.js +++ b/assets/garden_this-knowledge-hub_index.md.BAlSWWx9.js @@ -1 +1 @@ -import{d as s}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as i,Q as e,K as r,u as a,ag as o,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"This Knowledge Hub",-1),g=["innerHTML"],h=o('
Referenced by:Digital Gardens

This is my knowledge hub! It's a Digital Garden collecting my thoughts in varying levels of completeness on basically anything I have interest in. It's wiki-style, but not like Wikipedia. Each page is going to be biased and argumentative, and based on my understanding of the concept at the time of writing (with regular updates to reflect new understandings). On the more fleshed out articles I'll typically adopt the structure of a persuasive essay and include sources.

Since starting this digital garden, I've been writing a lot. Brief hiatuses aside, I'm writing on something nearly every day. I keep a lot of pages private, including all my daily journal pages, and only make a garden page public once I'm sufficiently happy with the state of it. As time goes on, I should also update and improve older pages to meet any increase in standards new pages have. This process of writing and updating pages has really helped me collect my thoughts and essentially check my understanding of a topic.

I write to my garden using Logseq. For more details on how the site gets generated and hosted, check out the page on My Personal Website. Of note, pushing garden page updates to the site is not an automatic process (which applies to bridged timeline posts as well, such as from Youtube or Github), so it's possible I'll have updated pages locally but they're not reflected in the site immediately.

Until something like Garden-RSS exists, we'll have to make do with /changelog which gives a git diff summary for every pushed change, in the form of a The IndieWeb stream as well as an RSS feed.

',6),_=JSON.parse('{"title":"This Knowledge Hub","description":"","frontmatter":{"public":"true","slug":"this-knowledge-hub","title":"This Knowledge Hub","prev":false,"next":false},"headers":[],"relativePath":"garden/this-knowledge-hub/index.md","filePath":"garden/this-knowledge-hub/index.md"}'),p={name:"garden/this-knowledge-hub/index.md"},b=Object.assign(p,{setup(u){const t=n();return(c,m)=>(l(),i("div",null,[d,e("p",null,[r("231 words, ~1 minute read. "),e("span",{innerHTML:a(s)[`site/${a(t).page.value.relativePath}`]},null,8,g)]),h]))}});export{_ as __pageData,b as default}; +import{d as s}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as i,Q as e,K as r,u as a,ag as o,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"This Knowledge Hub",-1),g=["innerHTML"],h=o('
Referenced by:Digital Gardens

This is my knowledge hub! It's a Digital Garden collecting my thoughts in varying levels of completeness on basically anything I have interest in. It's wiki-style, but not like Wikipedia. Each page is going to be biased and argumentative, and based on my understanding of the concept at the time of writing (with regular updates to reflect new understandings). On the more fleshed out articles I'll typically adopt the structure of a persuasive essay and include sources.

Since starting this digital garden, I've been writing a lot. Brief hiatuses aside, I'm writing on something nearly every day. I keep a lot of pages private, including all my daily journal pages, and only make a garden page public once I'm sufficiently happy with the state of it. As time goes on, I should also update and improve older pages to meet any increase in standards new pages have. This process of writing and updating pages has really helped me collect my thoughts and essentially check my understanding of a topic.

I write to my garden using Logseq. For more details on how the site gets generated and hosted, check out the page on My Personal Website. Of note, pushing garden page updates to the site is not an automatic process (which applies to bridged timeline posts as well, such as from Youtube or Github), so it's possible I'll have updated pages locally but they're not reflected in the site immediately.

Until something like Garden-RSS exists, we'll have to make do with /changelog which gives a git diff summary for every pushed change, in the form of a The IndieWeb stream as well as an RSS feed.

',6),_=JSON.parse('{"title":"This Knowledge Hub","description":"","frontmatter":{"public":"true","slug":"this-knowledge-hub","title":"This Knowledge Hub","prev":false,"next":false},"headers":[],"relativePath":"garden/this-knowledge-hub/index.md","filePath":"garden/this-knowledge-hub/index.md"}'),p={name:"garden/this-knowledge-hub/index.md"},b=Object.assign(p,{setup(u){const t=n();return(c,m)=>(l(),i("div",null,[d,e("p",null,[r("231 words, ~1 minute read. "),e("span",{innerHTML:a(s)[`site/${a(t).page.value.relativePath}`]},null,8,g)]),h]))}});export{_ as __pageData,b as default}; diff --git a/assets/garden_this-knowledge-hub_index.md.CLJqAHFR.lean.js b/assets/garden_this-knowledge-hub_index.md.BAlSWWx9.lean.js similarity index 92% rename from assets/garden_this-knowledge-hub_index.md.CLJqAHFR.lean.js rename to assets/garden_this-knowledge-hub_index.md.BAlSWWx9.lean.js index fd203fdfe..70cd6ce0d 100644 --- a/assets/garden_this-knowledge-hub_index.md.CLJqAHFR.lean.js +++ b/assets/garden_this-knowledge-hub_index.md.BAlSWWx9.lean.js @@ -1 +1 @@ -import{d as s}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as i,Q as e,K as r,u as a,ag as o,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"This Knowledge Hub",-1),g=["innerHTML"],h=o("",6),_=JSON.parse('{"title":"This Knowledge Hub","description":"","frontmatter":{"public":"true","slug":"this-knowledge-hub","title":"This Knowledge Hub","prev":false,"next":false},"headers":[],"relativePath":"garden/this-knowledge-hub/index.md","filePath":"garden/this-knowledge-hub/index.md"}'),p={name:"garden/this-knowledge-hub/index.md"},b=Object.assign(p,{setup(u){const t=n();return(c,m)=>(l(),i("div",null,[d,e("p",null,[r("231 words, ~1 minute read. "),e("span",{innerHTML:a(s)[`site/${a(t).page.value.relativePath}`]},null,8,g)]),h]))}});export{_ as __pageData,b as default}; +import{d as s}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as i,Q as e,K as r,u as a,ag as o,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"This Knowledge Hub",-1),g=["innerHTML"],h=o("",6),_=JSON.parse('{"title":"This Knowledge Hub","description":"","frontmatter":{"public":"true","slug":"this-knowledge-hub","title":"This Knowledge Hub","prev":false,"next":false},"headers":[],"relativePath":"garden/this-knowledge-hub/index.md","filePath":"garden/this-knowledge-hub/index.md"}'),p={name:"garden/this-knowledge-hub/index.md"},b=Object.assign(p,{setup(u){const t=n();return(c,m)=>(l(),i("div",null,[d,e("p",null,[r("231 words, ~1 minute read. "),e("span",{innerHTML:a(s)[`site/${a(t).page.value.relativePath}`]},null,8,g)]),h]))}});export{_ as __pageData,b as default}; diff --git a/assets/garden_trans-athletes-in-sports_index.md.DNc7lBCE.js b/assets/garden_trans-athletes-in-sports_index.md.Ckznm2z3.js similarity index 98% rename from assets/garden_trans-athletes-in-sports_index.md.DNc7lBCE.js rename to assets/garden_trans-athletes-in-sports_index.md.Ckznm2z3.js index a8b37f754..b809df5a4 100644 --- a/assets/garden_trans-athletes-in-sports_index.md.DNc7lBCE.js +++ b/assets/garden_trans-athletes-in-sports_index.md.Ckznm2z3.js @@ -1 +1 @@ -import{d as s}from"./chunks/git.data.D-Ga3RhB.js";import{M as r,q as n,Q as e,K as o,u as t,ag as i,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Trans athletes in sports",-1),c=["innerHTML"],d=i('
Referenced by:Everything is Political

Sports are meant to be competitions with winners and losers, which means intrinsically that one has to be better than the other. But we've determined certain advantages as "fair" ones and others as not, without fully acknowledging how fairness is just a Social Construct.

When Michael Phelps won gold medal after gold medal, no one complained that his naturally webbed feet were an "unfair" advantage, or put him in a separate league like we do for Gender. But when Caster Semenya, a cis woman with naturally higher levels of testosterone than other women, wanted to compete in track and field internationally she was told she'd need to take testosterone reducing medicine (until she years later won the case in Europe's human rights court, with caveats). If you have ADHD you're allowed to take performance enhancing drugs, but otherwise not. Coffee and protein could clearly be classified as performance enhancing drugs but for the fact we've socially defined PED as narrowly avoiding those substances. These are arbitrary rules that only seem fair to some people, because there is no objective fairness. So when trans athletes are attacked both when they compete with those of their assigned gender at birth as well as when they compete with those of their preferred gender, it's clear the motivation behind it all is not really about fairness in sports, but about making trans people go away. And yet, trans athletes tend to be an issue where even many socially leftist voices will discuss how "complicated" this issue is and even spread the idea that anti-trans policies are required in order to preserve fairness, such as The Young Turks as described in Why I Left TYT.

Being trans should not mean you are banned from competing or relegated to a division for just trans people. The argument is usually that trans individuals are either currently receiving or used to receive larger amounts of testosterone than those they'd be competing with. But the competition isn't about who has the more testosterone. Well, the argument continues, testosterone levels may be indicative of increased muscle growth. But muscle growth also isn't what the competition is about. It can be argued to indicate performance at the actual sport/activity the competition is over, but at this point isn't it too many layers of imperfect abstractions and assumptions? The person who wins is less tied to their actual ability and who happens to come out on top on each of these specific estimations.

There are many advantages one might have in sports, but contrary to a true meritocracy, our arbitrary distinctions on allowed vs disallowed advantages exposes the biases of our society, which are often racist, sexist, and transphobic. Therefore, appeals to "fairness" are explicit endorsements of those biases, namely bigotry.

I also support idubbbz discussing his support for trans athletes in 100 percent women, coming from the context of a boxer who has ran boxing competitions.

',7),b=JSON.parse('{"title":"Trans athletes in sports","description":"","frontmatter":{"public":"true","slug":"trans-athletes-in-sports","title":"Trans athletes in sports","prev":false,"next":false},"headers":[],"relativePath":"garden/trans-athletes-in-sports/index.md","filePath":"garden/trans-athletes-in-sports/index.md"}'),u={name:"garden/trans-athletes-in-sports/index.md"},y=Object.assign(u,{setup(p){const a=r();return(m,f)=>(l(),n("div",null,[h,e("p",null,[o("288 words, ~2 minute read. "),e("span",{innerHTML:t(s)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),d]))}});export{b as __pageData,y as default}; +import{d as s}from"./chunks/git.data.BcrWSzMU.js";import{M as r,q as n,Q as e,K as o,u as t,ag as i,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Trans athletes in sports",-1),c=["innerHTML"],d=i('
Referenced by:Everything is Political

Sports are meant to be competitions with winners and losers, which means intrinsically that one has to be better than the other. But we've determined certain advantages as "fair" ones and others as not, without fully acknowledging how fairness is just a Social Construct.

When Michael Phelps won gold medal after gold medal, no one complained that his naturally webbed feet were an "unfair" advantage, or put him in a separate league like we do for Gender. But when Caster Semenya, a cis woman with naturally higher levels of testosterone than other women, wanted to compete in track and field internationally she was told she'd need to take testosterone reducing medicine (until she years later won the case in Europe's human rights court, with caveats). If you have ADHD you're allowed to take performance enhancing drugs, but otherwise not. Coffee and protein could clearly be classified as performance enhancing drugs but for the fact we've socially defined PED as narrowly avoiding those substances. These are arbitrary rules that only seem fair to some people, because there is no objective fairness. So when trans athletes are attacked both when they compete with those of their assigned gender at birth as well as when they compete with those of their preferred gender, it's clear the motivation behind it all is not really about fairness in sports, but about making trans people go away. And yet, trans athletes tend to be an issue where even many socially leftist voices will discuss how "complicated" this issue is and even spread the idea that anti-trans policies are required in order to preserve fairness, such as The Young Turks as described in Why I Left TYT.

Being trans should not mean you are banned from competing or relegated to a division for just trans people. The argument is usually that trans individuals are either currently receiving or used to receive larger amounts of testosterone than those they'd be competing with. But the competition isn't about who has the more testosterone. Well, the argument continues, testosterone levels may be indicative of increased muscle growth. But muscle growth also isn't what the competition is about. It can be argued to indicate performance at the actual sport/activity the competition is over, but at this point isn't it too many layers of imperfect abstractions and assumptions? The person who wins is less tied to their actual ability and who happens to come out on top on each of these specific estimations.

There are many advantages one might have in sports, but contrary to a true meritocracy, our arbitrary distinctions on allowed vs disallowed advantages exposes the biases of our society, which are often racist, sexist, and transphobic. Therefore, appeals to "fairness" are explicit endorsements of those biases, namely bigotry.

I also support idubbbz discussing his support for trans athletes in 100 percent women, coming from the context of a boxer who has ran boxing competitions.

',7),b=JSON.parse('{"title":"Trans athletes in sports","description":"","frontmatter":{"public":"true","slug":"trans-athletes-in-sports","title":"Trans athletes in sports","prev":false,"next":false},"headers":[],"relativePath":"garden/trans-athletes-in-sports/index.md","filePath":"garden/trans-athletes-in-sports/index.md"}'),u={name:"garden/trans-athletes-in-sports/index.md"},y=Object.assign(u,{setup(p){const a=r();return(m,f)=>(l(),n("div",null,[h,e("p",null,[o("288 words, ~2 minute read. "),e("span",{innerHTML:t(s)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),d]))}});export{b as __pageData,y as default}; diff --git a/assets/garden_trans-athletes-in-sports_index.md.DNc7lBCE.lean.js b/assets/garden_trans-athletes-in-sports_index.md.Ckznm2z3.lean.js similarity index 92% rename from assets/garden_trans-athletes-in-sports_index.md.DNc7lBCE.lean.js rename to assets/garden_trans-athletes-in-sports_index.md.Ckznm2z3.lean.js index 96b4f5ee4..403d3e2f0 100644 --- a/assets/garden_trans-athletes-in-sports_index.md.DNc7lBCE.lean.js +++ b/assets/garden_trans-athletes-in-sports_index.md.Ckznm2z3.lean.js @@ -1 +1 @@ -import{d as s}from"./chunks/git.data.D-Ga3RhB.js";import{M as r,q as n,Q as e,K as o,u as t,ag as i,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Trans athletes in sports",-1),c=["innerHTML"],d=i("",7),b=JSON.parse('{"title":"Trans athletes in sports","description":"","frontmatter":{"public":"true","slug":"trans-athletes-in-sports","title":"Trans athletes in sports","prev":false,"next":false},"headers":[],"relativePath":"garden/trans-athletes-in-sports/index.md","filePath":"garden/trans-athletes-in-sports/index.md"}'),u={name:"garden/trans-athletes-in-sports/index.md"},y=Object.assign(u,{setup(p){const a=r();return(m,f)=>(l(),n("div",null,[h,e("p",null,[o("288 words, ~2 minute read. "),e("span",{innerHTML:t(s)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),d]))}});export{b as __pageData,y as default}; +import{d as s}from"./chunks/git.data.BcrWSzMU.js";import{M as r,q as n,Q as e,K as o,u as t,ag as i,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Trans athletes in sports",-1),c=["innerHTML"],d=i("",7),b=JSON.parse('{"title":"Trans athletes in sports","description":"","frontmatter":{"public":"true","slug":"trans-athletes-in-sports","title":"Trans athletes in sports","prev":false,"next":false},"headers":[],"relativePath":"garden/trans-athletes-in-sports/index.md","filePath":"garden/trans-athletes-in-sports/index.md"}'),u={name:"garden/trans-athletes-in-sports/index.md"},y=Object.assign(u,{setup(p){const a=r();return(m,f)=>(l(),n("div",null,[h,e("p",null,[o("288 words, ~2 minute read. "),e("span",{innerHTML:t(s)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),d]))}});export{b as __pageData,y as default}; diff --git a/assets/garden_v-ecs_index.md.BkjNGrNG.js b/assets/garden_v-ecs_index.md.47YLBRh-.js similarity index 97% rename from assets/garden_v-ecs_index.md.BkjNGrNG.js rename to assets/garden_v-ecs_index.md.47YLBRh-.js index 172c90aee..09e20a785 100644 --- a/assets/garden_v-ecs_index.md.BkjNGrNG.js +++ b/assets/garden_v-ecs_index.md.47YLBRh-.js @@ -1 +1 @@ -import{M as s,q as n,Q as e,K as o,u as a,ag as r,p as i,aM as l,aN as d,aO as c}from"./chunks/framework.Sr2_9k8k.js";import{d as m}from"./chunks/git.data.D-Ga3RhB.js";const p=e("h1",{class:"p-name"},"V-ecs",-1),h=["innerHTML"],g=r('
Tags:My Projects

V-ecs (pronounced "Vex") is a Vulkan-based engine I made for making highly moddable games and tools in Lua centered around the ECS design pattern and a work-stealing job system.

The engine works with "worlds", which are collections of systems and renderers. The engine comes with several worlds using systems and renderers I made, including a voxel world, an incremental game, and some test scenes. All of these include systems to render the fps as well as show a debug console by typing the grave key (`). The default world is a title screen that detects any worlds in the "worlds" folder and displays a button for each of them.

The original plans were to eventually put it on the steam workshop so people could more easily share their creations amongst each other, but I never became happy enough with the performance of the engine - the parallelization of the lua code involved a lot of overhead that severely limited performance.

Instead, I made a couple of worlds by myself - an infinite procedurally generated voxel world, a simple incremental game, and a more complex incremental game I call "Sands of Time".

The gameplay of Sands of Time was replicated in Kronos Chapter 2!

',10),T=JSON.parse('{"title":"V-ecs","description":"","frontmatter":{"public":"true","slug":"v-ecs","tags":["My Projects"],"title":"V-ecs","prev":false,"next":false},"headers":[],"relativePath":"garden/v-ecs/index.md","filePath":"garden/v-ecs/index.md"}'),u={name:"garden/v-ecs/index.md"},b=Object.assign(u,{setup(_){const t=s();return(f,v)=>(i(),n("div",null,[p,e("p",null,[o("209 words, ~1 minute read. "),e("span",{innerHTML:a(m)[`site/${a(t).page.value.relativePath}`]},null,8,h)]),g]))}});export{T as __pageData,b as default}; +import{M as s,q as n,Q as e,K as o,u as a,ag as r,p as i,aM as l,aN as d,aO as c}from"./chunks/framework.Sr2_9k8k.js";import{d as m}from"./chunks/git.data.BcrWSzMU.js";const p=e("h1",{class:"p-name"},"V-ecs",-1),h=["innerHTML"],g=r('
Tags:My Projects

V-ecs (pronounced "Vex") is a Vulkan-based engine I made for making highly moddable games and tools in Lua centered around the ECS design pattern and a work-stealing job system.

The engine works with "worlds", which are collections of systems and renderers. The engine comes with several worlds using systems and renderers I made, including a voxel world, an incremental game, and some test scenes. All of these include systems to render the fps as well as show a debug console by typing the grave key (`). The default world is a title screen that detects any worlds in the "worlds" folder and displays a button for each of them.

The original plans were to eventually put it on the steam workshop so people could more easily share their creations amongst each other, but I never became happy enough with the performance of the engine - the parallelization of the lua code involved a lot of overhead that severely limited performance.

Instead, I made a couple of worlds by myself - an infinite procedurally generated voxel world, a simple incremental game, and a more complex incremental game I call "Sands of Time".

The gameplay of Sands of Time was replicated in Kronos Chapter 2!

',10),T=JSON.parse('{"title":"V-ecs","description":"","frontmatter":{"public":"true","slug":"v-ecs","tags":["My Projects"],"title":"V-ecs","prev":false,"next":false},"headers":[],"relativePath":"garden/v-ecs/index.md","filePath":"garden/v-ecs/index.md"}'),u={name:"garden/v-ecs/index.md"},b=Object.assign(u,{setup(_){const t=s();return(f,v)=>(i(),n("div",null,[p,e("p",null,[o("209 words, ~1 minute read. "),e("span",{innerHTML:a(m)[`site/${a(t).page.value.relativePath}`]},null,8,h)]),g]))}});export{T as __pageData,b as default}; diff --git a/assets/garden_v-ecs_index.md.BkjNGrNG.lean.js b/assets/garden_v-ecs_index.md.47YLBRh-.lean.js similarity index 91% rename from assets/garden_v-ecs_index.md.BkjNGrNG.lean.js rename to assets/garden_v-ecs_index.md.47YLBRh-.lean.js index 715b8383f..875ef2e5d 100644 --- a/assets/garden_v-ecs_index.md.BkjNGrNG.lean.js +++ b/assets/garden_v-ecs_index.md.47YLBRh-.lean.js @@ -1 +1 @@ -import{M as s,q as n,Q as e,K as o,u as a,ag as r,p as i,aM as l,aN as d,aO as c}from"./chunks/framework.Sr2_9k8k.js";import{d as m}from"./chunks/git.data.D-Ga3RhB.js";const p=e("h1",{class:"p-name"},"V-ecs",-1),h=["innerHTML"],g=r("",10),T=JSON.parse('{"title":"V-ecs","description":"","frontmatter":{"public":"true","slug":"v-ecs","tags":["My Projects"],"title":"V-ecs","prev":false,"next":false},"headers":[],"relativePath":"garden/v-ecs/index.md","filePath":"garden/v-ecs/index.md"}'),u={name:"garden/v-ecs/index.md"},b=Object.assign(u,{setup(_){const t=s();return(f,v)=>(i(),n("div",null,[p,e("p",null,[o("209 words, ~1 minute read. "),e("span",{innerHTML:a(m)[`site/${a(t).page.value.relativePath}`]},null,8,h)]),g]))}});export{T as __pageData,b as default}; +import{M as s,q as n,Q as e,K as o,u as a,ag as r,p as i,aM as l,aN as d,aO as c}from"./chunks/framework.Sr2_9k8k.js";import{d as m}from"./chunks/git.data.BcrWSzMU.js";const p=e("h1",{class:"p-name"},"V-ecs",-1),h=["innerHTML"],g=r("",10),T=JSON.parse('{"title":"V-ecs","description":"","frontmatter":{"public":"true","slug":"v-ecs","tags":["My Projects"],"title":"V-ecs","prev":false,"next":false},"headers":[],"relativePath":"garden/v-ecs/index.md","filePath":"garden/v-ecs/index.md"}'),u={name:"garden/v-ecs/index.md"},b=Object.assign(u,{setup(_){const t=s();return(f,v)=>(i(),n("div",null,[p,e("p",null,[o("209 words, ~1 minute read. "),e("span",{innerHTML:a(m)[`site/${a(t).page.value.relativePath}`]},null,8,h)]),g]))}});export{T as __pageData,b as default}; diff --git a/assets/garden_video-essays_index.md.Dnw2MNSD.js b/assets/garden_video-essays_index.md.ChIx1pnZ.js similarity index 98% rename from assets/garden_video-essays_index.md.Dnw2MNSD.js rename to assets/garden_video-essays_index.md.ChIx1pnZ.js index 4367a2143..dd1dde41c 100644 --- a/assets/garden_video-essays_index.md.Dnw2MNSD.js +++ b/assets/garden_video-essays_index.md.ChIx1pnZ.js @@ -1 +1 @@ -import{d as s}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as i,Q as e,K as r,u as t,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Video Essays",-1),d=["innerHTML"],c=n('

Video essayists are an interesting case study here. I love video essays, they're often entertaining and you can tell the effort and care put into them. A lot of my favorite creators are video essayists, like hbomberguy, Folding Ideas, and Philosophy Tube (and probably more - its hard to keep track of my favorites since they upload infrequently). Unfortunately, video essays have now been recognized as successful ways to make videos with high watch time which has led to an explosion of video essays, with varying levels of skill, ethics, and effort put into researching the topics.

The format of video essays makes them feel credible - being longform, speaking authoritatively, and including relevant footage all contribute to this. However, none of those actually necessitate the creator being a subject matter expert.

"Video essayists" as a concept is a bit concerning because it positions those creators on a treadmill of constantly having to be (or at least appear to be) an expert of a brand new topic. I'm skeptical of any video essayist that uploads frequently or across a very large variety of topics.

Sometimes the extra duration of the footage is less to do with it deeply diving into the subject matter, but padding and fluff that's tangential to the point of the video. This is stuff like describing the process of how the creator did online research, or the methods they used to reach out to relevant people. In addition to padding the runtime, this shifts the focus off the subject of the video and onto the creator. I found this video to exemplify both this issue and many of my qualms with video essays.

Media Analysis Video Essays

Some video essays are very easy to make quickly and are doing so for profit. No video essay exemplifies this more than the media analysis video essay. While this doesn't apply to all video essays over media, all too often they'll just be summarizations of popular and nostalgic media that never gets into any meaningful analysis or offering genuine insights. It's just an easy way to make a lot of content, and thus watch time.

Personally, I think these specific video essays are slop taking advantage of people who like having their intellectual ego stroked. By watching media get lightly criticized, we position ourselves above the people actually out there creating original media. These videos are for the pretentious, who likely watch far more analysis of original media than original media itself. It's reaction content for those who feel they're above reaction content. This video essay (heh) goes further into the issues with this type of video essay.

Self Reflection

Part of my feelings towards video essays, and indeed such strong feelings as to include it here where its tangential at best, stems from self-confidence issues. Wondering if these articles I write are any better. I criticize video essays for being critical like an ouroboros, relying on this very statement to at least prove I'm aware of the hypocrisy.

Further Reading

Hey, did you know there's video essays about how video essays are bad? Well of course they are, a natural extension of the "thing bad" trend exemplified in the media analysis video essays and in Youtube culture at large. Anyways, I enjoyed this video covering other criticisms of video essays on Youtube.

Perhaps tangential, but I like Noodle's videos and he has one about critiquing video games, particularly popular titles.

',13),v=JSON.parse('{"title":"Video Essays","description":"","frontmatter":{"public":"true","slug":"video-essays","title":"Video Essays","prev":false,"next":false},"headers":[],"relativePath":"garden/video-essays/index.md","filePath":"garden/video-essays/index.md"}'),f={name:"garden/video-essays/index.md"},b=Object.assign(f,{setup(u){const a=o();return(y,p)=>(l(),i("div",null,[h,e("p",null,[r("561 words, ~3 minute read. "),e("span",{innerHTML:t(s)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),c]))}});export{v as __pageData,b as default}; +import{d as s}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as i,Q as e,K as r,u as t,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Video Essays",-1),d=["innerHTML"],c=n('

Video essayists are an interesting case study here. I love video essays, they're often entertaining and you can tell the effort and care put into them. A lot of my favorite creators are video essayists, like hbomberguy, Folding Ideas, and Philosophy Tube (and probably more - its hard to keep track of my favorites since they upload infrequently). Unfortunately, video essays have now been recognized as successful ways to make videos with high watch time which has led to an explosion of video essays, with varying levels of skill, ethics, and effort put into researching the topics.

The format of video essays makes them feel credible - being longform, speaking authoritatively, and including relevant footage all contribute to this. However, none of those actually necessitate the creator being a subject matter expert.

"Video essayists" as a concept is a bit concerning because it positions those creators on a treadmill of constantly having to be (or at least appear to be) an expert of a brand new topic. I'm skeptical of any video essayist that uploads frequently or across a very large variety of topics.

Sometimes the extra duration of the footage is less to do with it deeply diving into the subject matter, but padding and fluff that's tangential to the point of the video. This is stuff like describing the process of how the creator did online research, or the methods they used to reach out to relevant people. In addition to padding the runtime, this shifts the focus off the subject of the video and onto the creator. I found this video to exemplify both this issue and many of my qualms with video essays.

Media Analysis Video Essays

Some video essays are very easy to make quickly and are doing so for profit. No video essay exemplifies this more than the media analysis video essay. While this doesn't apply to all video essays over media, all too often they'll just be summarizations of popular and nostalgic media that never gets into any meaningful analysis or offering genuine insights. It's just an easy way to make a lot of content, and thus watch time.

Personally, I think these specific video essays are slop taking advantage of people who like having their intellectual ego stroked. By watching media get lightly criticized, we position ourselves above the people actually out there creating original media. These videos are for the pretentious, who likely watch far more analysis of original media than original media itself. It's reaction content for those who feel they're above reaction content. This video essay (heh) goes further into the issues with this type of video essay.

Self Reflection

Part of my feelings towards video essays, and indeed such strong feelings as to include it here where its tangential at best, stems from self-confidence issues. Wondering if these articles I write are any better. I criticize video essays for being critical like an ouroboros, relying on this very statement to at least prove I'm aware of the hypocrisy.

Further Reading

Hey, did you know there's video essays about how video essays are bad? Well of course they are, a natural extension of the "thing bad" trend exemplified in the media analysis video essays and in Youtube culture at large. Anyways, I enjoyed this video covering other criticisms of video essays on Youtube.

Perhaps tangential, but I like Noodle's videos and he has one about critiquing video games, particularly popular titles.

',13),v=JSON.parse('{"title":"Video Essays","description":"","frontmatter":{"public":"true","slug":"video-essays","title":"Video Essays","prev":false,"next":false},"headers":[],"relativePath":"garden/video-essays/index.md","filePath":"garden/video-essays/index.md"}'),f={name:"garden/video-essays/index.md"},b=Object.assign(f,{setup(u){const a=o();return(y,p)=>(l(),i("div",null,[h,e("p",null,[r("561 words, ~3 minute read. "),e("span",{innerHTML:t(s)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),c]))}});export{v as __pageData,b as default}; diff --git a/assets/garden_video-essays_index.md.Dnw2MNSD.lean.js b/assets/garden_video-essays_index.md.ChIx1pnZ.lean.js similarity index 91% rename from assets/garden_video-essays_index.md.Dnw2MNSD.lean.js rename to assets/garden_video-essays_index.md.ChIx1pnZ.lean.js index 811ec6358..17d36e756 100644 --- a/assets/garden_video-essays_index.md.Dnw2MNSD.lean.js +++ b/assets/garden_video-essays_index.md.ChIx1pnZ.lean.js @@ -1 +1 @@ -import{d as s}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as i,Q as e,K as r,u as t,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Video Essays",-1),d=["innerHTML"],c=n("",13),v=JSON.parse('{"title":"Video Essays","description":"","frontmatter":{"public":"true","slug":"video-essays","title":"Video Essays","prev":false,"next":false},"headers":[],"relativePath":"garden/video-essays/index.md","filePath":"garden/video-essays/index.md"}'),f={name:"garden/video-essays/index.md"},b=Object.assign(f,{setup(u){const a=o();return(y,p)=>(l(),i("div",null,[h,e("p",null,[r("561 words, ~3 minute read. "),e("span",{innerHTML:t(s)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),c]))}});export{v as __pageData,b as default}; +import{d as s}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as i,Q as e,K as r,u as t,ag as n,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Video Essays",-1),d=["innerHTML"],c=n("",13),v=JSON.parse('{"title":"Video Essays","description":"","frontmatter":{"public":"true","slug":"video-essays","title":"Video Essays","prev":false,"next":false},"headers":[],"relativePath":"garden/video-essays/index.md","filePath":"garden/video-essays/index.md"}'),f={name:"garden/video-essays/index.md"},b=Object.assign(f,{setup(u){const a=o();return(y,p)=>(l(),i("div",null,[h,e("p",null,[r("561 words, ~3 minute read. "),e("span",{innerHTML:t(s)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),c]))}});export{v as __pageData,b as default}; diff --git a/assets/garden_video-game-monetization_index.md.DDBSiidE.js b/assets/garden_video-game-monetization_index.md.DreEsxJJ.js similarity index 98% rename from assets/garden_video-game-monetization_index.md.DDBSiidE.js rename to assets/garden_video-game-monetization_index.md.DreEsxJJ.js index 5b1a9b8b0..f824f0920 100644 --- a/assets/garden_video-game-monetization_index.md.DDBSiidE.js +++ b/assets/garden_video-game-monetization_index.md.DreEsxJJ.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as o,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Video Game Monetization",-1),m=["innerHTML"],h=s('
Referenced by:Life is Strange

AAA games

They Clcost a lot of money to make, mostly due to the graphics arms race. The price required to make these games profitable would be much higher than the current price of AAA games.

Graphics would not justify significantly higher prices, and AAA studios know this. So instead they use the techniques to make more money without raising the base price:

Free-to-play games

Typically utilize MTX and ads in order to profit. Often extreme cases of designing games to compell players to spend money.

Indie developers

Trying to make a sustainable living as an indie developer is hard. The industry is packed with lots of competition, and drive prices people are willing to pay very low. Therefore, I don't blame indies for their monetization strategies, even if I consider them unethical or tainting the game design.

Ethical game monetization

Requirements:

  • Free demo
  • Paid base game
  • No MTX
  • Paid content expansions

The goal of the above is to allow players to determine if they enjoy the game without putting money down, and to ensure the game design cannot be tainted by the monetization.

I think having the gameplay affected by transactions of any kind taints the game design. This is a particularly controversial take in the context of communal benefits (e.g. one person donates and all players get a 2x buff for an hour, or a persistent buff based on number of patrons), which are generally seen as ethical.

',15),_=JSON.parse('{"title":"Video Game Monetization","description":"","frontmatter":{"public":"true","slug":"video-game-monetization","title":"Video Game Monetization","prev":false,"next":false},"headers":[],"relativePath":"garden/video-game-monetization/index.md","filePath":"garden/video-game-monetization/index.md"}'),p={name:"garden/video-game-monetization/index.md"},b=Object.assign(p,{setup(c){const t=n();return(g,u)=>(l(),o("div",null,[d,e("p",null,[r("250 words, ~1 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),h]))}});export{_ as __pageData,b as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as o,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Video Game Monetization",-1),m=["innerHTML"],h=s('
Referenced by:Life is Strange

AAA games

They Clcost a lot of money to make, mostly due to the graphics arms race. The price required to make these games profitable would be much higher than the current price of AAA games.

Graphics would not justify significantly higher prices, and AAA studios know this. So instead they use the techniques to make more money without raising the base price:

Free-to-play games

Typically utilize MTX and ads in order to profit. Often extreme cases of designing games to compell players to spend money.

Indie developers

Trying to make a sustainable living as an indie developer is hard. The industry is packed with lots of competition, and drive prices people are willing to pay very low. Therefore, I don't blame indies for their monetization strategies, even if I consider them unethical or tainting the game design.

Ethical game monetization

Requirements:

  • Free demo
  • Paid base game
  • No MTX
  • Paid content expansions

The goal of the above is to allow players to determine if they enjoy the game without putting money down, and to ensure the game design cannot be tainted by the monetization.

I think having the gameplay affected by transactions of any kind taints the game design. This is a particularly controversial take in the context of communal benefits (e.g. one person donates and all players get a 2x buff for an hour, or a persistent buff based on number of patrons), which are generally seen as ethical.

',15),_=JSON.parse('{"title":"Video Game Monetization","description":"","frontmatter":{"public":"true","slug":"video-game-monetization","title":"Video Game Monetization","prev":false,"next":false},"headers":[],"relativePath":"garden/video-game-monetization/index.md","filePath":"garden/video-game-monetization/index.md"}'),p={name:"garden/video-game-monetization/index.md"},b=Object.assign(p,{setup(c){const t=n();return(g,u)=>(l(),o("div",null,[d,e("p",null,[r("250 words, ~1 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),h]))}});export{_ as __pageData,b as default}; diff --git a/assets/garden_video-game-monetization_index.md.DDBSiidE.lean.js b/assets/garden_video-game-monetization_index.md.DreEsxJJ.lean.js similarity index 92% rename from assets/garden_video-game-monetization_index.md.DDBSiidE.lean.js rename to assets/garden_video-game-monetization_index.md.DreEsxJJ.lean.js index 402b49d05..f773781d9 100644 --- a/assets/garden_video-game-monetization_index.md.DDBSiidE.lean.js +++ b/assets/garden_video-game-monetization_index.md.DreEsxJJ.lean.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as o,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Video Game Monetization",-1),m=["innerHTML"],h=s("",15),_=JSON.parse('{"title":"Video Game Monetization","description":"","frontmatter":{"public":"true","slug":"video-game-monetization","title":"Video Game Monetization","prev":false,"next":false},"headers":[],"relativePath":"garden/video-game-monetization/index.md","filePath":"garden/video-game-monetization/index.md"}'),p={name:"garden/video-game-monetization/index.md"},b=Object.assign(p,{setup(c){const t=n();return(g,u)=>(l(),o("div",null,[d,e("p",null,[r("250 words, ~1 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),h]))}});export{_ as __pageData,b as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as o,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Video Game Monetization",-1),m=["innerHTML"],h=s("",15),_=JSON.parse('{"title":"Video Game Monetization","description":"","frontmatter":{"public":"true","slug":"video-game-monetization","title":"Video Game Monetization","prev":false,"next":false},"headers":[],"relativePath":"garden/video-game-monetization/index.md","filePath":"garden/video-game-monetization/index.md"}'),p={name:"garden/video-game-monetization/index.md"},b=Object.assign(p,{setup(c){const t=n();return(g,u)=>(l(),o("div",null,[d,e("p",null,[r("250 words, ~1 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),h]))}});export{_ as __pageData,b as default}; diff --git a/assets/garden_virality_index.md.Bw3Icu9N.js b/assets/garden_virality_index.md.DfY8NXAh.js similarity index 98% rename from assets/garden_virality_index.md.Bw3Icu9N.js rename to assets/garden_virality_index.md.DfY8NXAh.js index bb8c146d7..3f7c4a456 100644 --- a/assets/garden_virality_index.md.Bw3Icu9N.js +++ b/assets/garden_virality_index.md.DfY8NXAh.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as s,Q as e,K as n,u as a,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Virality",-1),h=["innerHTML"],c=r('
Referenced by:Digital Locality

Virality is the ability of something to "go viral" on a network - spread far and wide throughout the network. On traditional social media, this refers to how influencers and advertisers will have their content spread, but also specific posts from smaller posters can get picked up by the algorithm and spread as well.

Since there's only so much of people's attention to go around, social media has been described as an "attention economy". Under this framework, one could argue that social media is designed for "wealth accumulation", elevating a handful of accounts to celebrity status and limiting the reach of the masses. This dynamic much reflects the class antagonisms in a capitalist economy.

People "going viral"

On traditional social media, posts can be picked up by the algorithm and spread far and wide, causing the author to be inundated with unwanted attention, including negative or hateful attention. This can and has caused serious harm for both businesses and especially individuals. Traditional social media doesn't differentiate between the "living room" and "public square", which enforces this behavior. Digital Locality could help with this by its tendency to limit the reach of individual people or posts.

Movements on the fediverse

The Fediverse has been criticized for being "anti-viral", as described by Dr. Jonathan Flowers in a series of posts on whether the 2020 BLM movement could have happened on the fediverse. In general, I think something more Decentralized will fix these issues, so I'll address his main points.

Hashtags

Dr. Flowers argues that the success of BLM was dependent on the movement not relying on any specific person or post, but rather having the "cripthevote' hashtag that was visible platform wide and allowed people to see many posts about the movement and check for updates in realtime.

However, on the fediverse hashtags are instance local. This means they have to "jump" between instances (or escape, as he refers to it) in order to spread. This makes the movement much harder to spread across the federated network.

This may be solved by more properly Decentralized Social Media, since without a concept of instances there would naturally no longer be instance-local hashtags.

"No Politics" Rules

Since some instances on the fediverse have "no politics" rules, movements (which are inherently political) may be suppressed. Since identities are attached to instances, this means those users essentially cannot participate in the movement. Coupled with the usual issues with "no politics" rules, movements can be seriously impeded on the fediverse.

Decentralized Moderation can fix this issue by giving individuals more agency in moderation, and allowing them to evaluate their participation in movements on a case-by-case movement rather than relying on a blanket "no politics" rule

',15),b=JSON.parse('{"title":"Virality","description":"","frontmatter":{"public":"true","slug":"virality","title":"Virality","prev":false,"next":false},"headers":[],"relativePath":"garden/virality/index.md","filePath":"garden/virality/index.md"}'),u={name:"garden/virality/index.md"},y=Object.assign(u,{setup(p){const t=o();return(m,g)=>(l(),s("div",null,[d,e("p",null,[n("396 words, ~2 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,h)]),c]))}});export{b as __pageData,y as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as s,Q as e,K as n,u as a,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Virality",-1),h=["innerHTML"],c=r('
Referenced by:Digital Locality

Virality is the ability of something to "go viral" on a network - spread far and wide throughout the network. On traditional social media, this refers to how influencers and advertisers will have their content spread, but also specific posts from smaller posters can get picked up by the algorithm and spread as well.

Since there's only so much of people's attention to go around, social media has been described as an "attention economy". Under this framework, one could argue that social media is designed for "wealth accumulation", elevating a handful of accounts to celebrity status and limiting the reach of the masses. This dynamic much reflects the class antagonisms in a capitalist economy.

People "going viral"

On traditional social media, posts can be picked up by the algorithm and spread far and wide, causing the author to be inundated with unwanted attention, including negative or hateful attention. This can and has caused serious harm for both businesses and especially individuals. Traditional social media doesn't differentiate between the "living room" and "public square", which enforces this behavior. Digital Locality could help with this by its tendency to limit the reach of individual people or posts.

Movements on the fediverse

The Fediverse has been criticized for being "anti-viral", as described by Dr. Jonathan Flowers in a series of posts on whether the 2020 BLM movement could have happened on the fediverse. In general, I think something more Decentralized will fix these issues, so I'll address his main points.

Hashtags

Dr. Flowers argues that the success of BLM was dependent on the movement not relying on any specific person or post, but rather having the "cripthevote' hashtag that was visible platform wide and allowed people to see many posts about the movement and check for updates in realtime.

However, on the fediverse hashtags are instance local. This means they have to "jump" between instances (or escape, as he refers to it) in order to spread. This makes the movement much harder to spread across the federated network.

This may be solved by more properly Decentralized Social Media, since without a concept of instances there would naturally no longer be instance-local hashtags.

"No Politics" Rules

Since some instances on the fediverse have "no politics" rules, movements (which are inherently political) may be suppressed. Since identities are attached to instances, this means those users essentially cannot participate in the movement. Coupled with the usual issues with "no politics" rules, movements can be seriously impeded on the fediverse.

Decentralized Moderation can fix this issue by giving individuals more agency in moderation, and allowing them to evaluate their participation in movements on a case-by-case movement rather than relying on a blanket "no politics" rule

',15),b=JSON.parse('{"title":"Virality","description":"","frontmatter":{"public":"true","slug":"virality","title":"Virality","prev":false,"next":false},"headers":[],"relativePath":"garden/virality/index.md","filePath":"garden/virality/index.md"}'),u={name:"garden/virality/index.md"},y=Object.assign(u,{setup(p){const t=o();return(m,g)=>(l(),s("div",null,[d,e("p",null,[n("396 words, ~2 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,h)]),c]))}});export{b as __pageData,y as default}; diff --git a/assets/garden_virality_index.md.Bw3Icu9N.lean.js b/assets/garden_virality_index.md.DfY8NXAh.lean.js similarity index 91% rename from assets/garden_virality_index.md.Bw3Icu9N.lean.js rename to assets/garden_virality_index.md.DfY8NXAh.lean.js index 09eaa1a25..4883803a4 100644 --- a/assets/garden_virality_index.md.Bw3Icu9N.lean.js +++ b/assets/garden_virality_index.md.DfY8NXAh.lean.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as s,Q as e,K as n,u as a,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Virality",-1),h=["innerHTML"],c=r("",15),b=JSON.parse('{"title":"Virality","description":"","frontmatter":{"public":"true","slug":"virality","title":"Virality","prev":false,"next":false},"headers":[],"relativePath":"garden/virality/index.md","filePath":"garden/virality/index.md"}'),u={name:"garden/virality/index.md"},y=Object.assign(u,{setup(p){const t=o();return(m,g)=>(l(),s("div",null,[d,e("p",null,[n("396 words, ~2 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,h)]),c]))}});export{b as __pageData,y as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as s,Q as e,K as n,u as a,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Virality",-1),h=["innerHTML"],c=r("",15),b=JSON.parse('{"title":"Virality","description":"","frontmatter":{"public":"true","slug":"virality","title":"Virality","prev":false,"next":false},"headers":[],"relativePath":"garden/virality/index.md","filePath":"garden/virality/index.md"}'),u={name:"garden/virality/index.md"},y=Object.assign(u,{setup(p){const t=o();return(m,g)=>(l(),s("div",null,[d,e("p",null,[n("396 words, ~2 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,h)]),c]))}});export{b as __pageData,y as default}; diff --git a/assets/garden_vitepress_index.md.tx4a0n5q.js b/assets/garden_vitepress_index.md.DO0hrupk.js similarity index 94% rename from assets/garden_vitepress_index.md.tx4a0n5q.js rename to assets/garden_vitepress_index.md.DO0hrupk.js index 6fa6fbfa5..993a694e5 100644 --- a/assets/garden_vitepress_index.md.tx4a0n5q.js +++ b/assets/garden_vitepress_index.md.DO0hrupk.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as i,Q as e,K as t,u as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Vitepress",-1),d=["innerHTML"],p=e("hr",null,null,-1),c=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/my-personal-website/index.md"},"My Personal Website")],-1),u=e("p",null,[e("a",{href:"https://vitepress.dev",target:"_blank",rel:"noreferrer"},"Vitepress"),t(" is an "),e("a",{href:"/garden/open-source/"},"Open Source"),t(" static site generator")],-1),x=JSON.parse('{"title":"Vitepress","description":"","frontmatter":{"public":"true","slug":"vitepress","title":"Vitepress","prev":false,"next":false},"headers":[],"relativePath":"garden/vitepress/index.md","filePath":"garden/vitepress/index.md"}'),_={name:"garden/vitepress/index.md"},b=Object.assign(_,{setup(m){const a=n();return(h,f)=>(l(),i("div",null,[o,e("p",null,[t("4 words, ~0 minute read. "),e("span",{innerHTML:s(r)[`site/${s(a).page.value.relativePath}`]},null,8,d)]),p,c,u]))}});export{x as __pageData,b as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as i,Q as e,K as t,u as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Vitepress",-1),d=["innerHTML"],p=e("hr",null,null,-1),c=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/my-personal-website/index.md"},"My Personal Website")],-1),u=e("p",null,[e("a",{href:"https://vitepress.dev",target:"_blank",rel:"noreferrer"},"Vitepress"),t(" is an "),e("a",{href:"/garden/open-source/"},"Open Source"),t(" static site generator")],-1),x=JSON.parse('{"title":"Vitepress","description":"","frontmatter":{"public":"true","slug":"vitepress","title":"Vitepress","prev":false,"next":false},"headers":[],"relativePath":"garden/vitepress/index.md","filePath":"garden/vitepress/index.md"}'),_={name:"garden/vitepress/index.md"},b=Object.assign(_,{setup(m){const a=n();return(h,f)=>(l(),i("div",null,[o,e("p",null,[t("4 words, ~0 minute read. "),e("span",{innerHTML:s(r)[`site/${s(a).page.value.relativePath}`]},null,8,d)]),p,c,u]))}});export{x as __pageData,b as default}; diff --git a/assets/garden_vitepress_index.md.tx4a0n5q.lean.js b/assets/garden_vitepress_index.md.DO0hrupk.lean.js similarity index 94% rename from assets/garden_vitepress_index.md.tx4a0n5q.lean.js rename to assets/garden_vitepress_index.md.DO0hrupk.lean.js index 6fa6fbfa5..993a694e5 100644 --- a/assets/garden_vitepress_index.md.tx4a0n5q.lean.js +++ b/assets/garden_vitepress_index.md.DO0hrupk.lean.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as i,Q as e,K as t,u as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Vitepress",-1),d=["innerHTML"],p=e("hr",null,null,-1),c=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/my-personal-website/index.md"},"My Personal Website")],-1),u=e("p",null,[e("a",{href:"https://vitepress.dev",target:"_blank",rel:"noreferrer"},"Vitepress"),t(" is an "),e("a",{href:"/garden/open-source/"},"Open Source"),t(" static site generator")],-1),x=JSON.parse('{"title":"Vitepress","description":"","frontmatter":{"public":"true","slug":"vitepress","title":"Vitepress","prev":false,"next":false},"headers":[],"relativePath":"garden/vitepress/index.md","filePath":"garden/vitepress/index.md"}'),_={name:"garden/vitepress/index.md"},b=Object.assign(_,{setup(m){const a=n();return(h,f)=>(l(),i("div",null,[o,e("p",null,[t("4 words, ~0 minute read. "),e("span",{innerHTML:s(r)[`site/${s(a).page.value.relativePath}`]},null,8,d)]),p,c,u]))}});export{x as __pageData,b as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as i,Q as e,K as t,u as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const o=e("h1",{class:"p-name"},"Vitepress",-1),d=["innerHTML"],p=e("hr",null,null,-1),c=e("details",null,[e("summary",null,"Referenced by:"),e("a",{href:"/garden/my-personal-website/index.md"},"My Personal Website")],-1),u=e("p",null,[e("a",{href:"https://vitepress.dev",target:"_blank",rel:"noreferrer"},"Vitepress"),t(" is an "),e("a",{href:"/garden/open-source/"},"Open Source"),t(" static site generator")],-1),x=JSON.parse('{"title":"Vitepress","description":"","frontmatter":{"public":"true","slug":"vitepress","title":"Vitepress","prev":false,"next":false},"headers":[],"relativePath":"garden/vitepress/index.md","filePath":"garden/vitepress/index.md"}'),_={name:"garden/vitepress/index.md"},b=Object.assign(_,{setup(m){const a=n();return(h,f)=>(l(),i("div",null,[o,e("p",null,[t("4 words, ~0 minute read. "),e("span",{innerHTML:s(r)[`site/${s(a).page.value.relativePath}`]},null,8,d)]),p,c,u]))}});export{x as __pageData,b as default}; diff --git a/assets/garden_wanderstop_index.md.Br2zW1VJ.js b/assets/garden_wanderstop_index.md.CHEMH1CM.js similarity index 94% rename from assets/garden_wanderstop_index.md.Br2zW1VJ.js rename to assets/garden_wanderstop_index.md.CHEMH1CM.js index 4a99f5070..1d5c3485c 100644 --- a/assets/garden_wanderstop_index.md.Br2zW1VJ.js +++ b/assets/garden_wanderstop_index.md.CHEMH1CM.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as d,Q as e,K as a,u as t,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Wanderstop",-1),i=["innerHTML"],p=e("hr",null,null,-1),c=e("details",null,[e("summary",null,"Tags:"),e("a",{href:"/garden/davey-wreden/index.md"},"Davey Wreden")],-1),u=e("p",null,[e("a",{href:"https://www.wanderstopgame.com/",target:"_blank",rel:"noreferrer"},"Wanderstop"),a(" is the first game by "),e("a",{href:"/garden/ivy-road/"},"Ivy Road"),a(". It's a narrative focused cozy game")],-1),w=JSON.parse('{"title":"Wanderstop","description":"","frontmatter":{"public":"true","slug":"wanderstop","tags":["Davey Wreden"],"title":"Wanderstop","prev":false,"next":false},"headers":[],"relativePath":"garden/wanderstop/index.md","filePath":"garden/wanderstop/index.md"}'),_={name:"garden/wanderstop/index.md"},x=Object.assign(_,{setup(m){const n=s();return(h,f)=>(o(),d("div",null,[l,e("p",null,[a("8 words, ~0 minute read. "),e("span",{innerHTML:t(r)[`site/${t(n).page.value.relativePath}`]},null,8,i)]),p,c,u]))}});export{w as __pageData,x as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as d,Q as e,K as a,u as t,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Wanderstop",-1),i=["innerHTML"],p=e("hr",null,null,-1),c=e("details",null,[e("summary",null,"Tags:"),e("a",{href:"/garden/davey-wreden/index.md"},"Davey Wreden")],-1),u=e("p",null,[e("a",{href:"https://www.wanderstopgame.com/",target:"_blank",rel:"noreferrer"},"Wanderstop"),a(" is the first game by "),e("a",{href:"/garden/ivy-road/"},"Ivy Road"),a(". It's a narrative focused cozy game")],-1),w=JSON.parse('{"title":"Wanderstop","description":"","frontmatter":{"public":"true","slug":"wanderstop","tags":["Davey Wreden"],"title":"Wanderstop","prev":false,"next":false},"headers":[],"relativePath":"garden/wanderstop/index.md","filePath":"garden/wanderstop/index.md"}'),_={name:"garden/wanderstop/index.md"},x=Object.assign(_,{setup(m){const n=s();return(h,f)=>(o(),d("div",null,[l,e("p",null,[a("8 words, ~0 minute read. "),e("span",{innerHTML:t(r)[`site/${t(n).page.value.relativePath}`]},null,8,i)]),p,c,u]))}});export{w as __pageData,x as default}; diff --git a/assets/garden_wanderstop_index.md.Br2zW1VJ.lean.js b/assets/garden_wanderstop_index.md.CHEMH1CM.lean.js similarity index 94% rename from assets/garden_wanderstop_index.md.Br2zW1VJ.lean.js rename to assets/garden_wanderstop_index.md.CHEMH1CM.lean.js index 4a99f5070..1d5c3485c 100644 --- a/assets/garden_wanderstop_index.md.Br2zW1VJ.lean.js +++ b/assets/garden_wanderstop_index.md.CHEMH1CM.lean.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as s,q as d,Q as e,K as a,u as t,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Wanderstop",-1),i=["innerHTML"],p=e("hr",null,null,-1),c=e("details",null,[e("summary",null,"Tags:"),e("a",{href:"/garden/davey-wreden/index.md"},"Davey Wreden")],-1),u=e("p",null,[e("a",{href:"https://www.wanderstopgame.com/",target:"_blank",rel:"noreferrer"},"Wanderstop"),a(" is the first game by "),e("a",{href:"/garden/ivy-road/"},"Ivy Road"),a(". It's a narrative focused cozy game")],-1),w=JSON.parse('{"title":"Wanderstop","description":"","frontmatter":{"public":"true","slug":"wanderstop","tags":["Davey Wreden"],"title":"Wanderstop","prev":false,"next":false},"headers":[],"relativePath":"garden/wanderstop/index.md","filePath":"garden/wanderstop/index.md"}'),_={name:"garden/wanderstop/index.md"},x=Object.assign(_,{setup(m){const n=s();return(h,f)=>(o(),d("div",null,[l,e("p",null,[a("8 words, ~0 minute read. "),e("span",{innerHTML:t(r)[`site/${t(n).page.value.relativePath}`]},null,8,i)]),p,c,u]))}});export{w as __pageData,x as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as s,q as d,Q as e,K as a,u as t,p as o}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Wanderstop",-1),i=["innerHTML"],p=e("hr",null,null,-1),c=e("details",null,[e("summary",null,"Tags:"),e("a",{href:"/garden/davey-wreden/index.md"},"Davey Wreden")],-1),u=e("p",null,[e("a",{href:"https://www.wanderstopgame.com/",target:"_blank",rel:"noreferrer"},"Wanderstop"),a(" is the first game by "),e("a",{href:"/garden/ivy-road/"},"Ivy Road"),a(". It's a narrative focused cozy game")],-1),w=JSON.parse('{"title":"Wanderstop","description":"","frontmatter":{"public":"true","slug":"wanderstop","tags":["Davey Wreden"],"title":"Wanderstop","prev":false,"next":false},"headers":[],"relativePath":"garden/wanderstop/index.md","filePath":"garden/wanderstop/index.md"}'),_={name:"garden/wanderstop/index.md"},x=Object.assign(_,{setup(m){const n=s();return(h,f)=>(o(),d("div",null,[l,e("p",null,[a("8 words, ~0 minute read. "),e("span",{innerHTML:t(r)[`site/${t(n).page.value.relativePath}`]},null,8,i)]),p,c,u]))}});export{w as __pageData,x as default}; diff --git a/assets/garden_webrings_index.md.CxDR81HA.js b/assets/garden_webrings_index.md.C9YRZ8vb.js similarity index 96% rename from assets/garden_webrings_index.md.CxDR81HA.js rename to assets/garden_webrings_index.md.C9YRZ8vb.js index 8688edaa0..36319ada7 100644 --- a/assets/garden_webrings_index.md.CxDR81HA.js +++ b/assets/garden_webrings_index.md.C9YRZ8vb.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as l,q as s,Q as e,K as r,u as a,ag as n,p as o}from"./chunks/framework.Sr2_9k8k.js";const m=e("h1",{class:"p-name"},"Webrings",-1),c=["innerHTML"],d=n('
Referenced by:The Small Web

A collection of Personal Websites that link to each other

  • These websites are all endorsing each other
  • They form a network of related sites readers might be interested in
  • Built on human trust rather than algorithms

Commune has a vision for modern webrings

  • Have communities set up matrix spaces for chatting
  • Multiple spaces can contain the same room
  • Related communities can share a room about a relevant topic
    • e.g. a bunch of game development libraries shared a "Game Design" room
  • This allows smaller communities to grow from cross-pollinating with other related communities
  • Could Incremental Social host a shared "Incremental Games" room?
    • How to bridge one channel to multiple discord servers, since that's where most incremental games communities are
    • Would this be appealing to already large communities?
    • Would this be overwhelming to smaller communities?
    • Who would moderate?
',6),f=JSON.parse('{"title":"Webrings","description":"","frontmatter":{"public":"true","slug":"webrings","title":"Webrings","prev":false,"next":false},"headers":[],"relativePath":"garden/webrings/index.md","filePath":"garden/webrings/index.md"}'),u={name:"garden/webrings/index.md"},w=Object.assign(u,{setup(h){const t=l();return(g,p)=>(o(),s("div",null,[m,e("p",null,[r("139 words, ~1 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),d]))}});export{f as __pageData,w as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as l,q as s,Q as e,K as r,u as a,ag as n,p as o}from"./chunks/framework.Sr2_9k8k.js";const m=e("h1",{class:"p-name"},"Webrings",-1),c=["innerHTML"],d=n('
Referenced by:The Small Web

A collection of Personal Websites that link to each other

  • These websites are all endorsing each other
  • They form a network of related sites readers might be interested in
  • Built on human trust rather than algorithms

Commune has a vision for modern webrings

  • Have communities set up matrix spaces for chatting
  • Multiple spaces can contain the same room
  • Related communities can share a room about a relevant topic
    • e.g. a bunch of game development libraries shared a "Game Design" room
  • This allows smaller communities to grow from cross-pollinating with other related communities
  • Could Incremental Social host a shared "Incremental Games" room?
    • How to bridge one channel to multiple discord servers, since that's where most incremental games communities are
    • Would this be appealing to already large communities?
    • Would this be overwhelming to smaller communities?
    • Who would moderate?
',6),f=JSON.parse('{"title":"Webrings","description":"","frontmatter":{"public":"true","slug":"webrings","title":"Webrings","prev":false,"next":false},"headers":[],"relativePath":"garden/webrings/index.md","filePath":"garden/webrings/index.md"}'),u={name:"garden/webrings/index.md"},w=Object.assign(u,{setup(h){const t=l();return(g,p)=>(o(),s("div",null,[m,e("p",null,[r("139 words, ~1 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),d]))}});export{f as __pageData,w as default}; diff --git a/assets/garden_webrings_index.md.CxDR81HA.lean.js b/assets/garden_webrings_index.md.C9YRZ8vb.lean.js similarity index 91% rename from assets/garden_webrings_index.md.CxDR81HA.lean.js rename to assets/garden_webrings_index.md.C9YRZ8vb.lean.js index 859142206..8b352e7e1 100644 --- a/assets/garden_webrings_index.md.CxDR81HA.lean.js +++ b/assets/garden_webrings_index.md.C9YRZ8vb.lean.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as l,q as s,Q as e,K as r,u as a,ag as n,p as o}from"./chunks/framework.Sr2_9k8k.js";const m=e("h1",{class:"p-name"},"Webrings",-1),c=["innerHTML"],d=n("",6),f=JSON.parse('{"title":"Webrings","description":"","frontmatter":{"public":"true","slug":"webrings","title":"Webrings","prev":false,"next":false},"headers":[],"relativePath":"garden/webrings/index.md","filePath":"garden/webrings/index.md"}'),u={name:"garden/webrings/index.md"},w=Object.assign(u,{setup(h){const t=l();return(g,p)=>(o(),s("div",null,[m,e("p",null,[r("139 words, ~1 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),d]))}});export{f as __pageData,w as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as l,q as s,Q as e,K as r,u as a,ag as n,p as o}from"./chunks/framework.Sr2_9k8k.js";const m=e("h1",{class:"p-name"},"Webrings",-1),c=["innerHTML"],d=n("",6),f=JSON.parse('{"title":"Webrings","description":"","frontmatter":{"public":"true","slug":"webrings","title":"Webrings","prev":false,"next":false},"headers":[],"relativePath":"garden/webrings/index.md","filePath":"garden/webrings/index.md"}'),u={name:"garden/webrings/index.md"},w=Object.assign(u,{setup(h){const t=l();return(g,p)=>(o(),s("div",null,[m,e("p",null,[r("139 words, ~1 minute read. "),e("span",{innerHTML:a(i)[`site/${a(t).page.value.relativePath}`]},null,8,c)]),d]))}});export{f as __pageData,w as default}; diff --git a/assets/garden_weird_index.md.BSTJrWy3.js b/assets/garden_weird_index.md.BjZi1MDu.js similarity index 97% rename from assets/garden_weird_index.md.BSTJrWy3.js rename to assets/garden_weird_index.md.BjZi1MDu.js index 9fac97e4e..d99a3605e 100644 --- a/assets/garden_weird_index.md.BSTJrWy3.js +++ b/assets/garden_weird_index.md.BjZi1MDu.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as n,Q as e,K as s,u as a,ag as o,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Weird",-1),c=["innerHTML"],h=o('
Referenced by:CommuneFedi v2The Small Web

Weird is an Open Source project by the Commune team currently in development

Aims to make creating Personal Websites with Decentralized Identity available to everyone

  • Also plans on having paid tiers for giving people access to single user instances of various Fediverse tools

Long term, Weird wants to build a new better fediverse

',7),v=JSON.parse('{"title":"Weird","description":"","frontmatter":{"public":"true","slug":"weird","title":"Weird","prev":false,"next":false},"headers":[],"relativePath":"garden/weird/index.md","filePath":"garden/weird/index.md"}'),m={name:"garden/weird/index.md"},b=Object.assign(m,{setup(p){const r=i();return(u,f)=>(d(),n("div",null,[l,e("p",null,[s("114 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,c)]),h]))}});export{v as __pageData,b as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as n,Q as e,K as s,u as a,ag as o,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Weird",-1),c=["innerHTML"],h=o('
Referenced by:CommuneFedi v2The Small Web

Weird is an Open Source project by the Commune team currently in development

Aims to make creating Personal Websites with Decentralized Identity available to everyone

  • Also plans on having paid tiers for giving people access to single user instances of various Fediverse tools

Long term, Weird wants to build a new better fediverse

',7),v=JSON.parse('{"title":"Weird","description":"","frontmatter":{"public":"true","slug":"weird","title":"Weird","prev":false,"next":false},"headers":[],"relativePath":"garden/weird/index.md","filePath":"garden/weird/index.md"}'),m={name:"garden/weird/index.md"},b=Object.assign(m,{setup(p){const r=i();return(u,f)=>(d(),n("div",null,[l,e("p",null,[s("114 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,c)]),h]))}});export{v as __pageData,b as default}; diff --git a/assets/garden_weird_index.md.BSTJrWy3.lean.js b/assets/garden_weird_index.md.BjZi1MDu.lean.js similarity index 91% rename from assets/garden_weird_index.md.BSTJrWy3.lean.js rename to assets/garden_weird_index.md.BjZi1MDu.lean.js index bedceeac8..669f54b9c 100644 --- a/assets/garden_weird_index.md.BSTJrWy3.lean.js +++ b/assets/garden_weird_index.md.BjZi1MDu.lean.js @@ -1 +1 @@ -import{d as t}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as n,Q as e,K as s,u as a,ag as o,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Weird",-1),c=["innerHTML"],h=o("",7),v=JSON.parse('{"title":"Weird","description":"","frontmatter":{"public":"true","slug":"weird","title":"Weird","prev":false,"next":false},"headers":[],"relativePath":"garden/weird/index.md","filePath":"garden/weird/index.md"}'),m={name:"garden/weird/index.md"},b=Object.assign(m,{setup(p){const r=i();return(u,f)=>(d(),n("div",null,[l,e("p",null,[s("114 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,c)]),h]))}});export{v as __pageData,b as default}; +import{d as t}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as n,Q as e,K as s,u as a,ag as o,p as d}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Weird",-1),c=["innerHTML"],h=o("",7),v=JSON.parse('{"title":"Weird","description":"","frontmatter":{"public":"true","slug":"weird","title":"Weird","prev":false,"next":false},"headers":[],"relativePath":"garden/weird/index.md","filePath":"garden/weird/index.md"}'),m={name:"garden/weird/index.md"},b=Object.assign(m,{setup(p){const r=i();return(u,f)=>(d(),n("div",null,[l,e("p",null,[s("114 words, ~1 minute read. "),e("span",{innerHTML:a(t)[`site/${a(r).page.value.relativePath}`]},null,8,c)]),h]))}});export{v as __pageData,b as default}; diff --git a/assets/guide-to-incrementals_design_criticism_index.md.BcTt1ntM.js b/assets/guide-to-incrementals_design_criticism_index.md.CF3ptiyg.js similarity index 98% rename from assets/guide-to-incrementals_design_criticism_index.md.BcTt1ntM.js rename to assets/guide-to-incrementals_design_criticism_index.md.CF3ptiyg.js index 2c2f19bea..5aa7b72e5 100644 --- a/assets/guide-to-incrementals_design_criticism_index.md.BcTt1ntM.js +++ b/assets/guide-to-incrementals_design_criticism_index.md.CF3ptiyg.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as o,Q as e,K as s,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Guide to Incrementals/Navigating Criticism",-1),d=["innerHTML"],u=r('
Referenced by:Incremental SocialKronos

Developing games is fun and exciting and teaches a lot of wonderful skills - I enthusiastically encourage anyone with an interest in game development to try it out - and incremental games are a wonderful way to get started. However, there are many challenges young and inexperienced developers have to face, and I think the hardest one - harder than coding, debugging, balancing, etc. - is handling criticism. When you put your heart and soul into a game it is natural to feel very vulnerable. While I think there's a lot communities can do to ensure they're welcoming, positive and constructive with their criticisms, inevitably you will eventually read some, and potentially a lot, of comments that can deeply affect you. No one is immune to this, from young incremental game developers to the largest content creators you can think of. That's why it's important to be able to process and navigate criticism, because ultimately collecting feedback is essential to the journey to becoming a better developer. On this page, we'll explore how to embrace criticism, grow from it, and continue to post your games publicly with confidence.

Reading Feedback

Game development is a skill that takes time and practice to get truly great at. Criticism and other constructive feedback are vital to continually improving. It's useful to look at the criticism as solely a tool for improving this game and future games - that is to say, it should never be used against you as a person. Insults towards the developer(s) themselves are never okay and should not be allowed within whatever community you're sharing your works in. If you do come across a comment you interpret as an attack upon your person, you should report it. For other negative comments, try not to internalize them; instead, focus on improving the game. By distancing your own identity from your work emotionally, you can better analyze the game and use the feedback to your advantage.

Not all feedback is made equal, and you don't need to feel compelled to read and obey every piece of feedback you receive. Learn to distinguish between constructive feedback and unhelpful comments. Constructive feedback typically offers specific suggestions for improvement, while unhelpful comments are often vague or hurtful. Prioritize the former and disregard the latter. That said, most feedback you get will not be from game developers, so take specific suggestions with a grain of salt. Determine the actual problem they're experiencing, and design what you believe the best solution to that problem would be, regardless if that's the specific solution the player asked for. And keep in mind, due to different player preferences you'll never satisfy everyone, and you don't need to. Ultimately if even just you find the game fun, then that's a success.

Seeking Feedback

When deciding where to share your game, consider the type of players you anticipate getting, and the kind of feedback you can anticipate receiving. Different communities will have different levels of support for learning developers, and certain communities may prefer certain types of games or mechanics. It's important to get a diverse set of feedback focused on players you think will enjoy the specific game you're making.

Collecting feedback from other game developers is incredibly helpful. They've trained themselves to recognize good and bad game design and how to articulate the differences, and from my experience are much more likely to leave positive and constructive comments since they've been in your shoes before! They understand the struggles and can offer guidance and emotional support.

Responding to Feedback

Negative feedback can naturally feel like an attack, and it's okay to get angry. However, lashing back is never the appropriate response. It's best to cool off IRL, and keep in mind all the positive comments you've received. There's a concept in Psychology called negative bias that explains how negative feedback tends to stick with us much more prominently than positive feedback, so it's useful to regularly remind yourself of all the positive feedback you've received. Celebrate your successes, no matter how small they may seem - getting a game to a state you can publicly share it with people is an accomplishment in and of itself!

Remember your passion and your initial reasons for getting into game development. The journey will have its ups and downs, but staying true to your vision and passion will keep you motivated.

',12),v=JSON.parse('{"title":"Guide to Incrementals/Navigating Criticism","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/navigating-criticism","title":"Guide to Incrementals/Navigating Criticism","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/design/criticism/index.md","filePath":"guide-to-incrementals/design/criticism/index.md"}'),m={name:"guide-to-incrementals/design/criticism/index.md"},b=Object.assign(m,{setup(h){const a=n();return(g,p)=>(l(),o("div",null,[c,e("p",null,[s("747 words, ~4 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),u]))}});export{v as __pageData,b as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as o,Q as e,K as s,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Guide to Incrementals/Navigating Criticism",-1),d=["innerHTML"],u=r('
Referenced by:Incremental SocialKronos

Developing games is fun and exciting and teaches a lot of wonderful skills - I enthusiastically encourage anyone with an interest in game development to try it out - and incremental games are a wonderful way to get started. However, there are many challenges young and inexperienced developers have to face, and I think the hardest one - harder than coding, debugging, balancing, etc. - is handling criticism. When you put your heart and soul into a game it is natural to feel very vulnerable. While I think there's a lot communities can do to ensure they're welcoming, positive and constructive with their criticisms, inevitably you will eventually read some, and potentially a lot, of comments that can deeply affect you. No one is immune to this, from young incremental game developers to the largest content creators you can think of. That's why it's important to be able to process and navigate criticism, because ultimately collecting feedback is essential to the journey to becoming a better developer. On this page, we'll explore how to embrace criticism, grow from it, and continue to post your games publicly with confidence.

Reading Feedback

Game development is a skill that takes time and practice to get truly great at. Criticism and other constructive feedback are vital to continually improving. It's useful to look at the criticism as solely a tool for improving this game and future games - that is to say, it should never be used against you as a person. Insults towards the developer(s) themselves are never okay and should not be allowed within whatever community you're sharing your works in. If you do come across a comment you interpret as an attack upon your person, you should report it. For other negative comments, try not to internalize them; instead, focus on improving the game. By distancing your own identity from your work emotionally, you can better analyze the game and use the feedback to your advantage.

Not all feedback is made equal, and you don't need to feel compelled to read and obey every piece of feedback you receive. Learn to distinguish between constructive feedback and unhelpful comments. Constructive feedback typically offers specific suggestions for improvement, while unhelpful comments are often vague or hurtful. Prioritize the former and disregard the latter. That said, most feedback you get will not be from game developers, so take specific suggestions with a grain of salt. Determine the actual problem they're experiencing, and design what you believe the best solution to that problem would be, regardless if that's the specific solution the player asked for. And keep in mind, due to different player preferences you'll never satisfy everyone, and you don't need to. Ultimately if even just you find the game fun, then that's a success.

Seeking Feedback

When deciding where to share your game, consider the type of players you anticipate getting, and the kind of feedback you can anticipate receiving. Different communities will have different levels of support for learning developers, and certain communities may prefer certain types of games or mechanics. It's important to get a diverse set of feedback focused on players you think will enjoy the specific game you're making.

Collecting feedback from other game developers is incredibly helpful. They've trained themselves to recognize good and bad game design and how to articulate the differences, and from my experience are much more likely to leave positive and constructive comments since they've been in your shoes before! They understand the struggles and can offer guidance and emotional support.

Responding to Feedback

Negative feedback can naturally feel like an attack, and it's okay to get angry. However, lashing back is never the appropriate response. It's best to cool off IRL, and keep in mind all the positive comments you've received. There's a concept in Psychology called negative bias that explains how negative feedback tends to stick with us much more prominently than positive feedback, so it's useful to regularly remind yourself of all the positive feedback you've received. Celebrate your successes, no matter how small they may seem - getting a game to a state you can publicly share it with people is an accomplishment in and of itself!

Remember your passion and your initial reasons for getting into game development. The journey will have its ups and downs, but staying true to your vision and passion will keep you motivated.

',12),v=JSON.parse('{"title":"Guide to Incrementals/Navigating Criticism","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/navigating-criticism","title":"Guide to Incrementals/Navigating Criticism","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/design/criticism/index.md","filePath":"guide-to-incrementals/design/criticism/index.md"}'),m={name:"guide-to-incrementals/design/criticism/index.md"},b=Object.assign(m,{setup(h){const a=n();return(g,p)=>(l(),o("div",null,[c,e("p",null,[s("747 words, ~4 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),u]))}});export{v as __pageData,b as default}; diff --git a/assets/guide-to-incrementals_design_criticism_index.md.BcTt1ntM.lean.js b/assets/guide-to-incrementals_design_criticism_index.md.CF3ptiyg.lean.js similarity index 93% rename from assets/guide-to-incrementals_design_criticism_index.md.BcTt1ntM.lean.js rename to assets/guide-to-incrementals_design_criticism_index.md.CF3ptiyg.lean.js index b00f821ed..0e9c0b3de 100644 --- a/assets/guide-to-incrementals_design_criticism_index.md.BcTt1ntM.lean.js +++ b/assets/guide-to-incrementals_design_criticism_index.md.CF3ptiyg.lean.js @@ -1 +1 @@ -import{d as i}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as o,Q as e,K as s,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Guide to Incrementals/Navigating Criticism",-1),d=["innerHTML"],u=r("",12),v=JSON.parse('{"title":"Guide to Incrementals/Navigating Criticism","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/navigating-criticism","title":"Guide to Incrementals/Navigating Criticism","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/design/criticism/index.md","filePath":"guide-to-incrementals/design/criticism/index.md"}'),m={name:"guide-to-incrementals/design/criticism/index.md"},b=Object.assign(m,{setup(h){const a=n();return(g,p)=>(l(),o("div",null,[c,e("p",null,[s("747 words, ~4 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),u]))}});export{v as __pageData,b as default}; +import{d as i}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as o,Q as e,K as s,u as t,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"Guide to Incrementals/Navigating Criticism",-1),d=["innerHTML"],u=r("",12),v=JSON.parse('{"title":"Guide to Incrementals/Navigating Criticism","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/navigating-criticism","title":"Guide to Incrementals/Navigating Criticism","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/design/criticism/index.md","filePath":"guide-to-incrementals/design/criticism/index.md"}'),m={name:"guide-to-incrementals/design/criticism/index.md"},b=Object.assign(m,{setup(h){const a=n();return(g,p)=>(l(),o("div",null,[c,e("p",null,[s("747 words, ~4 minute read. "),e("span",{innerHTML:t(i)[`site/${t(a).page.value.relativePath}`]},null,8,d)]),u]))}});export{v as __pageData,b as default}; diff --git a/assets/guide-to-incrementals_index.md.DPTKaCuc.js b/assets/guide-to-incrementals_index.md.Bpq15UaX.js similarity index 98% rename from assets/guide-to-incrementals_index.md.DPTKaCuc.js rename to assets/guide-to-incrementals_index.md.Bpq15UaX.js index ff3310813..97c3e0ce1 100644 --- a/assets/guide-to-incrementals_index.md.DPTKaCuc.js +++ b/assets/guide-to-incrementals_index.md.Bpq15UaX.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as o,Q as e,K as s,u as a,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Guide to Incrementals",-1),m=["innerHTML"],c=r('
Referenced by:My Personal Website

This is a comprehensive guide to Incremental Games, a genre of video games. It will explore defining the genre, why it's appealing, and how to design and build your own incremental game. Along the way will be interactive examples, snippets from other creators, and relevant material to contextualize everything.

Note: This is an incomplete document. I want to keep adding opinions and opposing views from other incremental games developers, and add interactive examples to illustrate various points regarding game design and balancing. Consider this a living document - and see the changelog at the end.

Why am I making this?

That's a good question! What authority do I have to be making this guide? I haven't made the best incremental games, nor the most incremental games, certainly not the most popular ones either. But I do have some formal education in game development, know a lot of incremental game devs (as well as other game devs), and have a passionate interest in ludology, classifying genres, etc. I've also made a couple of incremental games) myself.

If you have any additional questions about my credentials or anything on this site, feel free to reach out!

Ludology

Making an Incremental

',11),y=JSON.parse('{"title":"Guide to Incrementals","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals","title":"Guide to Incrementals","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/index.md","filePath":"guide-to-incrementals/index.md"}'),g={name:"guide-to-incrementals/index.md"},v=Object.assign(g,{setup(h){const t=i();return(u,p)=>(l(),o("div",null,[d,e("p",null,[s("230 words, ~1 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),c]))}});export{y as __pageData,v as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as o,Q as e,K as s,u as a,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Guide to Incrementals",-1),m=["innerHTML"],c=r('
Referenced by:My Personal Website

This is a comprehensive guide to Incremental Games, a genre of video games. It will explore defining the genre, why it's appealing, and how to design and build your own incremental game. Along the way will be interactive examples, snippets from other creators, and relevant material to contextualize everything.

Note: This is an incomplete document. I want to keep adding opinions and opposing views from other incremental games developers, and add interactive examples to illustrate various points regarding game design and balancing. Consider this a living document - and see the changelog at the end.

Why am I making this?

That's a good question! What authority do I have to be making this guide? I haven't made the best incremental games, nor the most incremental games, certainly not the most popular ones either. But I do have some formal education in game development, know a lot of incremental game devs (as well as other game devs), and have a passionate interest in ludology, classifying genres, etc. I've also made a couple of incremental games) myself.

If you have any additional questions about my credentials or anything on this site, feel free to reach out!

Ludology

Making an Incremental

',11),y=JSON.parse('{"title":"Guide to Incrementals","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals","title":"Guide to Incrementals","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/index.md","filePath":"guide-to-incrementals/index.md"}'),g={name:"guide-to-incrementals/index.md"},v=Object.assign(g,{setup(h){const t=i();return(u,p)=>(l(),o("div",null,[d,e("p",null,[s("230 words, ~1 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),c]))}});export{y as __pageData,v as default}; diff --git a/assets/guide-to-incrementals_index.md.DPTKaCuc.lean.js b/assets/guide-to-incrementals_index.md.Bpq15UaX.lean.js similarity index 92% rename from assets/guide-to-incrementals_index.md.DPTKaCuc.lean.js rename to assets/guide-to-incrementals_index.md.Bpq15UaX.lean.js index 7d5e07e83..60ed91ca4 100644 --- a/assets/guide-to-incrementals_index.md.DPTKaCuc.lean.js +++ b/assets/guide-to-incrementals_index.md.Bpq15UaX.lean.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as i,q as o,Q as e,K as s,u as a,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Guide to Incrementals",-1),m=["innerHTML"],c=r("",11),y=JSON.parse('{"title":"Guide to Incrementals","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals","title":"Guide to Incrementals","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/index.md","filePath":"guide-to-incrementals/index.md"}'),g={name:"guide-to-incrementals/index.md"},v=Object.assign(g,{setup(h){const t=i();return(u,p)=>(l(),o("div",null,[d,e("p",null,[s("230 words, ~1 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),c]))}});export{y as __pageData,v as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as i,q as o,Q as e,K as s,u as a,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const d=e("h1",{class:"p-name"},"Guide to Incrementals",-1),m=["innerHTML"],c=r("",11),y=JSON.parse('{"title":"Guide to Incrementals","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals","title":"Guide to Incrementals","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/index.md","filePath":"guide-to-incrementals/index.md"}'),g={name:"guide-to-incrementals/index.md"},v=Object.assign(g,{setup(h){const t=i();return(u,p)=>(l(),o("div",null,[d,e("p",null,[s("230 words, ~1 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),c]))}});export{y as __pageData,v as default}; diff --git a/assets/guide-to-incrementals_ludology_appeal-developers_index.md.D48oheRE.js b/assets/guide-to-incrementals_ludology_appeal-developers_index.md.CimyBWKE.js similarity index 98% rename from assets/guide-to-incrementals_ludology_appeal-developers_index.md.D48oheRE.js rename to assets/guide-to-incrementals_ludology_appeal-developers_index.md.CimyBWKE.js index b2977a29d..e1039ad89 100644 --- a/assets/guide-to-incrementals_ludology_appeal-developers_index.md.D48oheRE.js +++ b/assets/guide-to-incrementals_ludology_appeal-developers_index.md.CimyBWKE.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as i,Q as e,K as r,u as a,ag as l,p as s}from"./chunks/framework.Sr2_9k8k.js";const m=e("h1",{class:"p-name"},"Guide to Incrementals/Appeal to Developers",-1),d=["innerHTML"],c=l('
Referenced by:Incremental SocialKronos

There are a lot of developers in the incremental games community - the genre seems to draw them in, and convert a lot of players into developers. Let's explore the reasons why this genre appeals to developers.

Incrementals are Easy to Make

Compared to other genres, incrementals have quite low expectations. You don't need to make fancy art, or music, or lay things out nicely. If you can make a button and learn the few lines of code necessary to make a number go up, you can make an incremental. This low threshold makes the genre perfect for those who are actively learning to code and haven't developed any gamedev-related skills yet.

Additionally, unlike other genres incrementals are uniquely easy to implement in a normal web page - no need to worry about rendering sprites, moving them around, implementing physics, etc. New developers can just use HTML to add a button, and the game is now available in your browser. You don't need to choose an engine, have admin privileges, or hell for the dedicated you don't even need a computer - there are tools for web development that run in the browser itself, so you can technically use your phone if that's all you have.

Javascript is a perfectly viable language for making web games, whereas other genres are typically going to require using other more difficult languages to learn. There are countless javascript tutorials that start from 0 knowledge of programming, making it incredibly accessible to beginners.

Players are Easy to Find

Once you've finished your game and uploaded it on github pages or itch or just copied the link if you're using glitch or replit (all of which are easy to do), anyone can now play the game in their browser. This low barrier to entry has shown tremendous success in getting completely unknown developers to have thousands of plays.

The incremental games community, which mostly centers around r/incremental_games, is always looking for new games and tends to flood any new ones posted with initial players.

Having your games be played can be incredibly motivating, and the community makes it quite clear that you can expect players to play your game. These communities - both for incremental games in general as well as game-specific communities - tend to be very developer friendly as well. A lot of the developers know each other, and welcome new developers with open arms, often with dedicated channels for programming help and discussions.

Monetization

I'd like to clarify that everything I've said above mainly applies to web-based incrementals. Incremental games are also incredibly popular on mobile, but with a much different culture and community. Many mobile gamers will still participate in the web-focused community for the culture. This web-focused community has a culture that has been criticized for being "anti-monetization". Ads, IAPs, and similar forms of monetization are often criticized, mainly due to the abundance of completely non-monetized games available from hobbyist developers. There are exceptions, like paid games often being considered fine, like Increlution or Stuck in Time, or donation ware games like kittens game, but even popular games that have IAP see some level of regular criticism, like NGU Idle, Idle Skilling, or Idle Pins. A large part of this can be explained by the community being hyper-aware of the addictive) nature of this genre and its susceptibility to exploiting players.

On mobile, however, monetization is the norm and expected. If an incremental game is available on mobile, it almost certainly will be monetized, and mobile players are aware and accepting of that. Mobile incremental games, due to their addictive nature, tend to make a lot of money. It's very lucrative, and therefore these games are quite abundant on mobile storefronts.

',14),b=JSON.parse('{"title":"Guide to Incrementals/Appeal to Developers","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/appeal-to-developers","title":"Guide to Incrementals/Appeal to Developers","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/ludology/appeal-developers/index.md","filePath":"guide-to-incrementals/ludology/appeal-developers/index.md"}'),p={name:"guide-to-incrementals/ludology/appeal-developers/index.md"},v=Object.assign(p,{setup(h){const t=o();return(u,g)=>(s(),i("div",null,[m,e("p",null,[r("636 words, ~3 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),c]))}});export{b as __pageData,v as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as i,Q as e,K as r,u as a,ag as l,p as s}from"./chunks/framework.Sr2_9k8k.js";const m=e("h1",{class:"p-name"},"Guide to Incrementals/Appeal to Developers",-1),d=["innerHTML"],c=l('
Referenced by:Incremental SocialKronos

There are a lot of developers in the incremental games community - the genre seems to draw them in, and convert a lot of players into developers. Let's explore the reasons why this genre appeals to developers.

Incrementals are Easy to Make

Compared to other genres, incrementals have quite low expectations. You don't need to make fancy art, or music, or lay things out nicely. If you can make a button and learn the few lines of code necessary to make a number go up, you can make an incremental. This low threshold makes the genre perfect for those who are actively learning to code and haven't developed any gamedev-related skills yet.

Additionally, unlike other genres incrementals are uniquely easy to implement in a normal web page - no need to worry about rendering sprites, moving them around, implementing physics, etc. New developers can just use HTML to add a button, and the game is now available in your browser. You don't need to choose an engine, have admin privileges, or hell for the dedicated you don't even need a computer - there are tools for web development that run in the browser itself, so you can technically use your phone if that's all you have.

Javascript is a perfectly viable language for making web games, whereas other genres are typically going to require using other more difficult languages to learn. There are countless javascript tutorials that start from 0 knowledge of programming, making it incredibly accessible to beginners.

Players are Easy to Find

Once you've finished your game and uploaded it on github pages or itch or just copied the link if you're using glitch or replit (all of which are easy to do), anyone can now play the game in their browser. This low barrier to entry has shown tremendous success in getting completely unknown developers to have thousands of plays.

The incremental games community, which mostly centers around r/incremental_games, is always looking for new games and tends to flood any new ones posted with initial players.

Having your games be played can be incredibly motivating, and the community makes it quite clear that you can expect players to play your game. These communities - both for incremental games in general as well as game-specific communities - tend to be very developer friendly as well. A lot of the developers know each other, and welcome new developers with open arms, often with dedicated channels for programming help and discussions.

Monetization

I'd like to clarify that everything I've said above mainly applies to web-based incrementals. Incremental games are also incredibly popular on mobile, but with a much different culture and community. Many mobile gamers will still participate in the web-focused community for the culture. This web-focused community has a culture that has been criticized for being "anti-monetization". Ads, IAPs, and similar forms of monetization are often criticized, mainly due to the abundance of completely non-monetized games available from hobbyist developers. There are exceptions, like paid games often being considered fine, like Increlution or Stuck in Time, or donation ware games like kittens game, but even popular games that have IAP see some level of regular criticism, like NGU Idle, Idle Skilling, or Idle Pins. A large part of this can be explained by the community being hyper-aware of the addictive) nature of this genre and its susceptibility to exploiting players.

On mobile, however, monetization is the norm and expected. If an incremental game is available on mobile, it almost certainly will be monetized, and mobile players are aware and accepting of that. Mobile incremental games, due to their addictive nature, tend to make a lot of money. It's very lucrative, and therefore these games are quite abundant on mobile storefronts.

',14),b=JSON.parse('{"title":"Guide to Incrementals/Appeal to Developers","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/appeal-to-developers","title":"Guide to Incrementals/Appeal to Developers","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/ludology/appeal-developers/index.md","filePath":"guide-to-incrementals/ludology/appeal-developers/index.md"}'),p={name:"guide-to-incrementals/ludology/appeal-developers/index.md"},v=Object.assign(p,{setup(h){const t=o();return(u,g)=>(s(),i("div",null,[m,e("p",null,[r("636 words, ~3 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),c]))}});export{b as __pageData,v as default}; diff --git a/assets/guide-to-incrementals_ludology_appeal-developers_index.md.D48oheRE.lean.js b/assets/guide-to-incrementals_ludology_appeal-developers_index.md.CimyBWKE.lean.js similarity index 93% rename from assets/guide-to-incrementals_ludology_appeal-developers_index.md.D48oheRE.lean.js rename to assets/guide-to-incrementals_ludology_appeal-developers_index.md.CimyBWKE.lean.js index e428473b0..97d341d63 100644 --- a/assets/guide-to-incrementals_ludology_appeal-developers_index.md.D48oheRE.lean.js +++ b/assets/guide-to-incrementals_ludology_appeal-developers_index.md.CimyBWKE.lean.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as i,Q as e,K as r,u as a,ag as l,p as s}from"./chunks/framework.Sr2_9k8k.js";const m=e("h1",{class:"p-name"},"Guide to Incrementals/Appeal to Developers",-1),d=["innerHTML"],c=l("",14),b=JSON.parse('{"title":"Guide to Incrementals/Appeal to Developers","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/appeal-to-developers","title":"Guide to Incrementals/Appeal to Developers","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/ludology/appeal-developers/index.md","filePath":"guide-to-incrementals/ludology/appeal-developers/index.md"}'),p={name:"guide-to-incrementals/ludology/appeal-developers/index.md"},v=Object.assign(p,{setup(h){const t=o();return(u,g)=>(s(),i("div",null,[m,e("p",null,[r("636 words, ~3 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),c]))}});export{b as __pageData,v as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as i,Q as e,K as r,u as a,ag as l,p as s}from"./chunks/framework.Sr2_9k8k.js";const m=e("h1",{class:"p-name"},"Guide to Incrementals/Appeal to Developers",-1),d=["innerHTML"],c=l("",14),b=JSON.parse('{"title":"Guide to Incrementals/Appeal to Developers","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/appeal-to-developers","title":"Guide to Incrementals/Appeal to Developers","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/ludology/appeal-developers/index.md","filePath":"guide-to-incrementals/ludology/appeal-developers/index.md"}'),p={name:"guide-to-incrementals/ludology/appeal-developers/index.md"},v=Object.assign(p,{setup(h){const t=o();return(u,g)=>(s(),i("div",null,[m,e("p",null,[r("636 words, ~3 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),c]))}});export{b as __pageData,v as default}; diff --git a/assets/guide-to-incrementals_ludology_appeal-gamers_index.md.DEXlbts1.js b/assets/guide-to-incrementals_ludology_appeal-gamers_index.md.Cmpvya3x.js similarity index 99% rename from assets/guide-to-incrementals_ludology_appeal-gamers_index.md.DEXlbts1.js rename to assets/guide-to-incrementals_ludology_appeal-gamers_index.md.Cmpvya3x.js index 5655a2aef..6b480b7b6 100644 --- a/assets/guide-to-incrementals_ludology_appeal-gamers_index.md.DEXlbts1.js +++ b/assets/guide-to-incrementals_ludology_appeal-gamers_index.md.Cmpvya3x.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as i,Q as e,K as s,u as a,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Guide to Incrementals/Appeal to Players",-1),m=["innerHTML"],g=r('
Referenced by:Incremental SocialKronos

This is something that has been discussed and analyzed by many people, and to some extent, I feel like everything that can be said on the topic already has. However, a lot of these analyses are from the perspective of those with not as much experience and involvement within the genre as I'd argue would be necessary for a fully contextualized answer. I'm interested in ludology and part of that includes interpreting games as art, and to that end what constitutes a game, let alone a "good game". Incremental games are oft criticized, unfairly in my biased opinion, of not even constituting games, such as was posited by this polygon article.

Numbers Going Up

This is a very common response to why people enjoy incremental games, although it's not one I find compels me personally, and I suspect it might be a stand-in for progression) or Guide to Incrementals/What is Content?. But reportedly, some people do just like seeing big numbers. I must reiterate I suspect the actual cause is seeing big numbers in context though - if you start at 1e1000 of a currency and get to 1e1001, that isn't going to feel as satisfying as going from 1e10 to 1e100, and in any case, I don't think a button that just adds a zero to your number will feel quite satisfying - I believe its the sense of having made progress, and comparing where you are to where you started and feeling like you've earned your way here that is enjoyable.

Progression

I think a strong sense of progression is seen as very enjoyable to many players of all sorts of genres - engine builder board games, RPGs, rogue_lites_, etc. Incremental games tend to have an extremely exaggerated sense of progression, which makes them very appealing.

Meta-progression is when games have some sort of progression that persists when other progress gets lost - for example, upgrades that persist between runs of a roguelite game. These are common mechanics in incremental games - in fact, its not uncommon to have multiple of these reset mechanics nested on top of each other, each with their own meta-progression. These are satisfying to players, although they can be a bit controversial. These mechanics can often be seen as an optional crutch, and in roguelite games, players often challenge themselves to win without any meta progression. Essentially these challenges argue that meta-progression de-emphasizes player skill by replacing it with time served. Incremental games, through their exaggerated progression, eschew that possibility though - they make it impossible to beat without the meta progression systems, as the meta-progression becomes an entire chapter of the gameplay. I'd argue this does not detract from the game, however, and is actually a part of what makes incremental games, and roguelikes, enjoyable to many players: meta-progression augments the increases in skill the player is naturally gaining as they play. In effect, it's not replacing the skill increase, but exaggerating it to make it feel more real to the player.

Effortlessness

Incremental games are so easy, a lot of them even have you progress while you're not playing! Part of the appeal is being able to feel like you're making progress while doing something actually productive - multitasking, in a way. In this sense, the game is more of a fidget toy - not something to think hard about and play actively, but something to click a few buttons every so often while you're paying attention to a lecture or studying or working. Of course, not all incremental games lend themselves to being played this way - it's specifically "idle" games that work like this. These are games that take an incredibly long amount of time to see all the content, stretching it as thin as possible, but they aren't expecting you to be sitting at your device playing it the entire time. They expect you to leave and come back later to make a bit of progress and repeat the cycle.

If you look at the higher-level play of most games, you'll see them perform difficult feats with ease and speed. They'll achieve a "flow state" that takes all their knowledge and experience of the game and uses it to play the game as instinctively as possible. It's incredible to watch things like Slay the Spire speed runs or competitive DDR-likes. I'd argue the goal of a lot of games with a competitive scene is to get so good that the game becomes effortless. In that sense, a game that allows you to reach that point earlier isn't any less legitimate, but rather lowers the barrier to entry by allowing more people to get "really good" at the game. And to be clear, (most) incremental games aren't trivially easy - they, and to an extent, every game will have some level of learning and improvement over time.

Addiction

A lot of these reasons for why incremental games appeal may have reminded you of why gambling appeals to people, particularly those prone to addiction. Indeed, incremental games are quite often criticized for their similarity to a skinner box. Some have gone as far as to say incremental games as a genre are commenting that all games are skinner boxes). The argument goes that some games are not fun, but rather condition players into continuing to play without actually getting anything from the experience. When tied to real-world money this is seen as predatory, and to a lesser extent, even free games may be feeding the addictive sides of people and making them more prone to seek out gambling or micro-transaction heavy games.

While incremental games can be fun and even healthy in certain contexts, they can exacerbate video game addiction more than other genres. If you feel like playing incremental games is taking priority over other things in your life, or manipulating your sleep schedule, it may be prudent to seek help. See r/StopGaming for resources.

Since incremental games are often built on extrinsic motivations in the form of progression systems, it's hard to argue whether players continue to play because they are enjoying the gameplay, or if they are just conditioned to keep doing it because the game keeps rewarding them. Unfortunately, it can often feel like it's the latter, as there isn't typically anything compelling about the "gameplay" of clicking a button and waiting. There may be a significant overlap between those who enjoy incremental games and those who are most prone to addiction, and there are often posts on r/incremental_games about someone either struggling with or overcoming video game addiction.

Strategy

Incremental games could be considered a subset of strategy games), and inherit the appeals of strategy games. This includes the appeal of feeling like you've found a good solution to a puzzle, or that you're learning more about the game and are improving at making decisions within it.

Note that strategy games are not all the same difficulty, as well. Cookie Clicker is probably easier than Starcraft 2 (although late game may beg to differ). Plenty of incremental games can be used as evidence that "easier" strategies may have their separate appeal to harder strategy games - players like to feel smart and that they figured the game out and have optimized or mastered it, and the game being easier doesn't detract from that sense of accomplishment as much as it allows more and more users to be able to reach the point where they gain that sense.

Avoiding Staleness

Incremental games tend to have "paradigm shifts", where the gameplay changes in a meaningful way at various times throughout the progression of the game. These upset and change the gameplay loop, which helps keep them from stagnating. This constant "freshness" to the gameplay can keep players engaged for longer, compared to a game with a repetitive and static gameplay loop.

Good Game Design

Incremental games tend to show their game design "plainly", so it's more readily apparent if a game has good game design while playing, even if you're not looking for it. While different players have different preferences and might enjoy different types of games more than others, there are underlying good and bad game design principles that players will notice the effects of. To be clear, this isn't talking about stuff like big numbers being enjoyable, where I can comfortably agree to disagree with other players. They don't intrinsically make my experience better, but I'm aware of those for whom it does and I won't argue against their feelings. However, the game designer in me does feel like there are some extremely clear-cut examples of good and bad game design philosophies.

Let's start by giving an example of a mechanic I think can be easily and strongly argued is good game design. There are of course many examples, but a personal favorite of mine is how DOOM encourages aggressive gameplay by linking health drops to melee attacks. It has an intended experience it's trying to give the player - immersing themselves as DOOM guy, who would not hide behind cover when low on health - and this mechanic does a great job at encouraging and effectively teaching players to behave properly. This is in sharp contrast to shooters like Call of Duty, which have you regen health passively, encouraging players to hide behind cover and wait after getting hit. Note that I'm not arguing CoD is poorly designed, as the games have different intended experiences. I'm specifically praising DOOM for having a mechanic that does a good job at ensuring the player has that intended experience.

To contrast with an example I think is bad game design, let's talk about shields in souls-likes. This is a bit of a famous example, and I highly recommend this video essay which spends quite a good bit of time on this topic. Essentially, the argument boils down to players of earlier games in the souls games using shields too much - playing slowly, conservatively, and ultimately having less fun. Players wanted to feel safe, so they ended up playing in a way that ruined the experience for them. The developers solved this by removing shields, apart from an intentionally bad one effectively mocking the playstyle, and it did its job at getting players to play more aggressively, and often have more fun.

To bring the conversation back to incrementals, I'm incredibly opinionated on what makes a good incremental game, which I'll discuss in the game design section. Suffice it to say, incremental games rely more on good game design than other genres, due to not having much to distract from bad game design. This helps (although imperfectly - gamers are a bit too tolerant of bad game design!) well-designed games rise to the top within the genre.

Artistic Merit

The discussion of whether video games are art has resulted in a pretty universal "yes, they are", but with some games the argument may still crop up. The reason why Incremental games are sometimes questioned is due to their perceived lack of complexity. However, even setting aside the fact that if players are having fun then it's not time wasted, I think games can have artistic merit that supersedes the necessity of having (any / engaging / "deep") gameplay. Incremental games are no less legitimate of a game or the "art" label because of any lack perceived lack of depth. For what it's worth, most art can be consumed with more ease than any video game - any painting, movie, sculpture, etc.

A lot of incrementals have a narrative context that can similarly qualify them as art. Cookie Clicker is, as has been pointed out numerous times before, commenting on excess and increasing production beyond any reasonable limits - devolving into increasing production for its own sake. Indeed, a lot of incremental games are written to comment upon various concepts like capitalism or tropes in games, as discussed when defining Incrementals). However, I'd like to argue most incremental games are still art, even without any narrative context. "Art" as a concept is pretty nebulous already, but I personally like those who define it as an act of expression more than any physical result. The creator and the context within which they created the art, and any meaning they put into it, are all relevant and a part of the art itself. Most incremental games have artistic merit from things like why the creator made it, why they chose to make it an incremental game, and why they made any particular design decision. Hell, even if you play through an entire incremental game without a single thought or feeling, that very fact it elicited nothing can itself be artistic merit!

I'm not an art major, and I may be taking a somewhat extreme take on what is art and what has artistic merit, but I'd argue the overall point stands that games, and incremental games specifically, can have artistic merit, which appeals to many gamers.

',29),b=JSON.parse('{"title":"Guide to Incrementals/Appeal to Players","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/appeal-to-players","title":"Guide to Incrementals/Appeal to Players","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/ludology/appeal-gamers/index.md","filePath":"guide-to-incrementals/ludology/appeal-gamers/index.md"}'),c={name:"guide-to-incrementals/ludology/appeal-gamers/index.md"},w=Object.assign(c,{setup(d){const t=o();return(p,u)=>(l(),i("div",null,[h,e("p",null,[s("2166 words, ~12 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),g]))}});export{b as __pageData,w as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as i,Q as e,K as s,u as a,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Guide to Incrementals/Appeal to Players",-1),m=["innerHTML"],g=r('
Referenced by:Incremental SocialKronos

This is something that has been discussed and analyzed by many people, and to some extent, I feel like everything that can be said on the topic already has. However, a lot of these analyses are from the perspective of those with not as much experience and involvement within the genre as I'd argue would be necessary for a fully contextualized answer. I'm interested in ludology and part of that includes interpreting games as art, and to that end what constitutes a game, let alone a "good game". Incremental games are oft criticized, unfairly in my biased opinion, of not even constituting games, such as was posited by this polygon article.

Numbers Going Up

This is a very common response to why people enjoy incremental games, although it's not one I find compels me personally, and I suspect it might be a stand-in for progression) or Guide to Incrementals/What is Content?. But reportedly, some people do just like seeing big numbers. I must reiterate I suspect the actual cause is seeing big numbers in context though - if you start at 1e1000 of a currency and get to 1e1001, that isn't going to feel as satisfying as going from 1e10 to 1e100, and in any case, I don't think a button that just adds a zero to your number will feel quite satisfying - I believe its the sense of having made progress, and comparing where you are to where you started and feeling like you've earned your way here that is enjoyable.

Progression

I think a strong sense of progression is seen as very enjoyable to many players of all sorts of genres - engine builder board games, RPGs, rogue_lites_, etc. Incremental games tend to have an extremely exaggerated sense of progression, which makes them very appealing.

Meta-progression is when games have some sort of progression that persists when other progress gets lost - for example, upgrades that persist between runs of a roguelite game. These are common mechanics in incremental games - in fact, its not uncommon to have multiple of these reset mechanics nested on top of each other, each with their own meta-progression. These are satisfying to players, although they can be a bit controversial. These mechanics can often be seen as an optional crutch, and in roguelite games, players often challenge themselves to win without any meta progression. Essentially these challenges argue that meta-progression de-emphasizes player skill by replacing it with time served. Incremental games, through their exaggerated progression, eschew that possibility though - they make it impossible to beat without the meta progression systems, as the meta-progression becomes an entire chapter of the gameplay. I'd argue this does not detract from the game, however, and is actually a part of what makes incremental games, and roguelikes, enjoyable to many players: meta-progression augments the increases in skill the player is naturally gaining as they play. In effect, it's not replacing the skill increase, but exaggerating it to make it feel more real to the player.

Effortlessness

Incremental games are so easy, a lot of them even have you progress while you're not playing! Part of the appeal is being able to feel like you're making progress while doing something actually productive - multitasking, in a way. In this sense, the game is more of a fidget toy - not something to think hard about and play actively, but something to click a few buttons every so often while you're paying attention to a lecture or studying or working. Of course, not all incremental games lend themselves to being played this way - it's specifically "idle" games that work like this. These are games that take an incredibly long amount of time to see all the content, stretching it as thin as possible, but they aren't expecting you to be sitting at your device playing it the entire time. They expect you to leave and come back later to make a bit of progress and repeat the cycle.

If you look at the higher-level play of most games, you'll see them perform difficult feats with ease and speed. They'll achieve a "flow state" that takes all their knowledge and experience of the game and uses it to play the game as instinctively as possible. It's incredible to watch things like Slay the Spire speed runs or competitive DDR-likes. I'd argue the goal of a lot of games with a competitive scene is to get so good that the game becomes effortless. In that sense, a game that allows you to reach that point earlier isn't any less legitimate, but rather lowers the barrier to entry by allowing more people to get "really good" at the game. And to be clear, (most) incremental games aren't trivially easy - they, and to an extent, every game will have some level of learning and improvement over time.

Addiction

A lot of these reasons for why incremental games appeal may have reminded you of why gambling appeals to people, particularly those prone to addiction. Indeed, incremental games are quite often criticized for their similarity to a skinner box. Some have gone as far as to say incremental games as a genre are commenting that all games are skinner boxes). The argument goes that some games are not fun, but rather condition players into continuing to play without actually getting anything from the experience. When tied to real-world money this is seen as predatory, and to a lesser extent, even free games may be feeding the addictive sides of people and making them more prone to seek out gambling or micro-transaction heavy games.

While incremental games can be fun and even healthy in certain contexts, they can exacerbate video game addiction more than other genres. If you feel like playing incremental games is taking priority over other things in your life, or manipulating your sleep schedule, it may be prudent to seek help. See r/StopGaming for resources.

Since incremental games are often built on extrinsic motivations in the form of progression systems, it's hard to argue whether players continue to play because they are enjoying the gameplay, or if they are just conditioned to keep doing it because the game keeps rewarding them. Unfortunately, it can often feel like it's the latter, as there isn't typically anything compelling about the "gameplay" of clicking a button and waiting. There may be a significant overlap between those who enjoy incremental games and those who are most prone to addiction, and there are often posts on r/incremental_games about someone either struggling with or overcoming video game addiction.

Strategy

Incremental games could be considered a subset of strategy games), and inherit the appeals of strategy games. This includes the appeal of feeling like you've found a good solution to a puzzle, or that you're learning more about the game and are improving at making decisions within it.

Note that strategy games are not all the same difficulty, as well. Cookie Clicker is probably easier than Starcraft 2 (although late game may beg to differ). Plenty of incremental games can be used as evidence that "easier" strategies may have their separate appeal to harder strategy games - players like to feel smart and that they figured the game out and have optimized or mastered it, and the game being easier doesn't detract from that sense of accomplishment as much as it allows more and more users to be able to reach the point where they gain that sense.

Avoiding Staleness

Incremental games tend to have "paradigm shifts", where the gameplay changes in a meaningful way at various times throughout the progression of the game. These upset and change the gameplay loop, which helps keep them from stagnating. This constant "freshness" to the gameplay can keep players engaged for longer, compared to a game with a repetitive and static gameplay loop.

Good Game Design

Incremental games tend to show their game design "plainly", so it's more readily apparent if a game has good game design while playing, even if you're not looking for it. While different players have different preferences and might enjoy different types of games more than others, there are underlying good and bad game design principles that players will notice the effects of. To be clear, this isn't talking about stuff like big numbers being enjoyable, where I can comfortably agree to disagree with other players. They don't intrinsically make my experience better, but I'm aware of those for whom it does and I won't argue against their feelings. However, the game designer in me does feel like there are some extremely clear-cut examples of good and bad game design philosophies.

Let's start by giving an example of a mechanic I think can be easily and strongly argued is good game design. There are of course many examples, but a personal favorite of mine is how DOOM encourages aggressive gameplay by linking health drops to melee attacks. It has an intended experience it's trying to give the player - immersing themselves as DOOM guy, who would not hide behind cover when low on health - and this mechanic does a great job at encouraging and effectively teaching players to behave properly. This is in sharp contrast to shooters like Call of Duty, which have you regen health passively, encouraging players to hide behind cover and wait after getting hit. Note that I'm not arguing CoD is poorly designed, as the games have different intended experiences. I'm specifically praising DOOM for having a mechanic that does a good job at ensuring the player has that intended experience.

To contrast with an example I think is bad game design, let's talk about shields in souls-likes. This is a bit of a famous example, and I highly recommend this video essay which spends quite a good bit of time on this topic. Essentially, the argument boils down to players of earlier games in the souls games using shields too much - playing slowly, conservatively, and ultimately having less fun. Players wanted to feel safe, so they ended up playing in a way that ruined the experience for them. The developers solved this by removing shields, apart from an intentionally bad one effectively mocking the playstyle, and it did its job at getting players to play more aggressively, and often have more fun.

To bring the conversation back to incrementals, I'm incredibly opinionated on what makes a good incremental game, which I'll discuss in the game design section. Suffice it to say, incremental games rely more on good game design than other genres, due to not having much to distract from bad game design. This helps (although imperfectly - gamers are a bit too tolerant of bad game design!) well-designed games rise to the top within the genre.

Artistic Merit

The discussion of whether video games are art has resulted in a pretty universal "yes, they are", but with some games the argument may still crop up. The reason why Incremental games are sometimes questioned is due to their perceived lack of complexity. However, even setting aside the fact that if players are having fun then it's not time wasted, I think games can have artistic merit that supersedes the necessity of having (any / engaging / "deep") gameplay. Incremental games are no less legitimate of a game or the "art" label because of any lack perceived lack of depth. For what it's worth, most art can be consumed with more ease than any video game - any painting, movie, sculpture, etc.

A lot of incrementals have a narrative context that can similarly qualify them as art. Cookie Clicker is, as has been pointed out numerous times before, commenting on excess and increasing production beyond any reasonable limits - devolving into increasing production for its own sake. Indeed, a lot of incremental games are written to comment upon various concepts like capitalism or tropes in games, as discussed when defining Incrementals). However, I'd like to argue most incremental games are still art, even without any narrative context. "Art" as a concept is pretty nebulous already, but I personally like those who define it as an act of expression more than any physical result. The creator and the context within which they created the art, and any meaning they put into it, are all relevant and a part of the art itself. Most incremental games have artistic merit from things like why the creator made it, why they chose to make it an incremental game, and why they made any particular design decision. Hell, even if you play through an entire incremental game without a single thought or feeling, that very fact it elicited nothing can itself be artistic merit!

I'm not an art major, and I may be taking a somewhat extreme take on what is art and what has artistic merit, but I'd argue the overall point stands that games, and incremental games specifically, can have artistic merit, which appeals to many gamers.

',29),b=JSON.parse('{"title":"Guide to Incrementals/Appeal to Players","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/appeal-to-players","title":"Guide to Incrementals/Appeal to Players","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/ludology/appeal-gamers/index.md","filePath":"guide-to-incrementals/ludology/appeal-gamers/index.md"}'),c={name:"guide-to-incrementals/ludology/appeal-gamers/index.md"},w=Object.assign(c,{setup(d){const t=o();return(p,u)=>(l(),i("div",null,[h,e("p",null,[s("2166 words, ~12 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),g]))}});export{b as __pageData,w as default}; diff --git a/assets/guide-to-incrementals_ludology_appeal-gamers_index.md.DEXlbts1.lean.js b/assets/guide-to-incrementals_ludology_appeal-gamers_index.md.Cmpvya3x.lean.js similarity index 93% rename from assets/guide-to-incrementals_ludology_appeal-gamers_index.md.DEXlbts1.lean.js rename to assets/guide-to-incrementals_ludology_appeal-gamers_index.md.Cmpvya3x.lean.js index f56b1dab9..fb22e797a 100644 --- a/assets/guide-to-incrementals_ludology_appeal-gamers_index.md.DEXlbts1.lean.js +++ b/assets/guide-to-incrementals_ludology_appeal-gamers_index.md.Cmpvya3x.lean.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as i,Q as e,K as s,u as a,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Guide to Incrementals/Appeal to Players",-1),m=["innerHTML"],g=r("",29),b=JSON.parse('{"title":"Guide to Incrementals/Appeal to Players","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/appeal-to-players","title":"Guide to Incrementals/Appeal to Players","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/ludology/appeal-gamers/index.md","filePath":"guide-to-incrementals/ludology/appeal-gamers/index.md"}'),c={name:"guide-to-incrementals/ludology/appeal-gamers/index.md"},w=Object.assign(c,{setup(d){const t=o();return(p,u)=>(l(),i("div",null,[h,e("p",null,[s("2166 words, ~12 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),g]))}});export{b as __pageData,w as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as i,Q as e,K as s,u as a,ag as r,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Guide to Incrementals/Appeal to Players",-1),m=["innerHTML"],g=r("",29),b=JSON.parse('{"title":"Guide to Incrementals/Appeal to Players","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/appeal-to-players","title":"Guide to Incrementals/Appeal to Players","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/ludology/appeal-gamers/index.md","filePath":"guide-to-incrementals/ludology/appeal-gamers/index.md"}'),c={name:"guide-to-incrementals/ludology/appeal-gamers/index.md"},w=Object.assign(c,{setup(d){const t=o();return(p,u)=>(l(),i("div",null,[h,e("p",null,[s("2166 words, ~12 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,m)]),g]))}});export{b as __pageData,w as default}; diff --git a/assets/guide-to-incrementals_ludology_content_index.md.BMb_w6x8.js b/assets/guide-to-incrementals_ludology_content_index.md.zhZ55mqj.js similarity index 99% rename from assets/guide-to-incrementals_ludology_content_index.md.BMb_w6x8.js rename to assets/guide-to-incrementals_ludology_content_index.md.zhZ55mqj.js index 62dea0f0b..9d8018dac 100644 --- a/assets/guide-to-incrementals_ludology_content_index.md.BMb_w6x8.js +++ b/assets/guide-to-incrementals_ludology_content_index.md.zhZ55mqj.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as i,Q as e,K as s,u as t,ag as r,p as h}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Guide to Incrementals/What is Content?",-1),c=["innerHTML"],u=r('
Referenced by:Incremental SocialKronos

If you've been in the incremental games community for any amount of time, you'll quickly find the number one thing players want is content. They want as much of it as possible! The most popular incremental games have tons of content, so they just keep stretching on and on and on, introducing mechanic after mechanic, and players love it. In fact, players seem to value the amount of content over the quality of any specific content. However, there's a bit of a lack of understanding concerning what content is, and I'd like to explore what counts as content, and how we measure it. As a baseline definition, I think "content" can just be described as the parts of the game that engage the player, but to truly understand it we need to contextualize what that means and how it affects the gameplay experience.

To clarify the purpose of this page, my goal is not to get (too) nitpicky or to attack games with "low content". There's nothing wrong with short / low-content games - I'm quite a big fan of those games myself! This is mostly targeted toward those who ask for content and settle for "long" games, and those who want to provide content but want to make sure they're not just artificially inflating the game. Ultimately, I suppose the goal is to just reduce the amount of artificially inflated content for the sake of having a "longer" game.

Interaction

I think it should be a fairly non-controversial opinion that time spent solely waiting should not count towards content. That is not including the time reading various effects or making decisions in your head, but rather time spent waiting for a condition to be met so you can re-engage with the game.

That is not to say games should necessarily try to minimize this time. Plenty of games lead towards more infrequent interaction and still get popular. In fact, these games appeal to many gamers who want to have something to check up on in between bursts of working on some other activity. These games seem to have fallen slightly out of fashion amongst modern incremental games, but they're still fully valid. The point I'm trying to make here is just that this time is not content. As an extreme example, a game with no interactions and just a counter that goes up every second could safely be said to have 0 content beyond the time it takes to understand what's going on. If it has a list of "goals" to hit, then the time understanding those goals and a short time after achieving each one could be considered content, but not the idle times in between.

Let's take a look at the opposite end of the spectrum - interaction that is so frequent as to become mindless. This is any mechanic where you need to spam-click something to progress. This may be a more controversial take, but I do not believe this constitutes content either. It does not engage the player, because each consecutive click blends together and they do not individually change the gameplay experience. That is to say, a single click and 100 clicks are not meaningfully different in terms of engaging the player. I'd go as far as to say clicking 100 times would be actively worse, as it's artificially delaying the next piece of actual content, alongside the issues of accessibility and potentially causing RSI.

Repeatable Purchases

Imagine an entity in a game that you can purchase multiple times, each time it performs the same thing but for a higher cost. These are incredibly common, from the buildings in cookie clicker to the units in swarm sim to the IP and EP multipliers in antimatter dimensions. However, how much content is each specific purchase? Is it content beyond the first purchase? Does it have diminishing returns? What if you are oscillating between two different repeatable purchases? How much content is lost when you automate) away a repeatable purchase?

I don't want to take too harsh a stance against repeatable purchases. They're useful tools and can be used in a myriad of interesting ways. I feel they do become "stale" or less meaningful content over time, and this happens exponentially quickly the more frequently it can be purchased. A classic example that I believe goes too far is the IP/EP multipliers in Antimatter Dimensions. I would go as far as to say they are a chore and do not provide any meaningful content after you've bought them a couple of times. It's a method for inflating numbers (effectively making every OOM a 5x step instead of 10x), that punishes the player progression-wise whenever they forget to max it again, and eventually gets automated away as a reward to the player for making enough progress.

Just to voice the other side of this argument, Acamaeda defended the IP multiplier as giving the player a "good" upgrade every OOM. I can understand that to a point and need to clarify I'm mainly criticizing IP/EP multipliers after they've been introduced for a while. In fact, I would defend the multipliers for a short while after they're introduced using the same logic I would use to defend normal dimensions as repeatable purchases, at least pre-infinity. There's "content" to be had in looking at what dimensions will become affordable next, and then choosing which to buy amongst those. The IP/EP multipliers, early into infinity or eternity respectively, provide another option that gets put into that mental queue of things to buy with each OOM reached - although the optimal order is often quite trivial and not particularly engaging.

The IP/EP multipliers are not the only repeatable purchase in antimatter dimensions I take offense to. The time dimensions are also a series of repeatable purchases, that are all so similar and static that it doesn't take long before you never need to put any thought into buying them, how much you're buying at once, or the order you buy them in - you just press max all and move on. The entire tab could've been just the max all button and it would not have made a difference beyond the start of the eternity layer. The normal dimensions technically have this problem as well, but since you're constantly getting antimatter the order feels like it has a larger impact and it's more meaningful content, right up until they're automated away. Infinity dimensions are a compromise between the two, so I'm highlighting time dimensions here as the most egregious.

Following Instructions

We're getting more and more controversial as we go along! Let's talk about how linear content is not content now (in some circumstances). A trend in incremental games is adding difficulty by adding a web of effects that abstract the true change you can expect from any specific purchase or decision you make. If a game is both linear and sufficiently abstracts the effect of player decisions, then the player will no longer be engaging with the content - they'll simply be clicking on things as they become available. This isn't necessarily a bad thing, as plenty of players don't mind this style of gameplay, but I'd argue once you reach a point where players don't bother reading the effects, those interactions are no longer truly content. Note that unlike the previous qualifiers mentioned, this qualifier is based on the player, and therefore subjective. In effect, it's a spectrum where the more complicated the web of effects becomes, the more likely it is to disengage the player.

This over-complicatedness leading to disengaging the player can also happen from non-linear gameplay. If the web of effects becomes sufficiently complicated and finding the optimal progression route too time-consuming to discover, players will seek out guides from other players who've completed the game. The second they do this, the game effectively becomes linearly following the instructions of the guide and all the above criticisms apply. Similarly to as before, though, this is a spectrum and not everyone will seek out a guide at the same level of difficulty.

Automation

Automation is a staple of the genre, but it has certain implications for the design of the game. Why, when new content is introduced, must the older content be automated away - why is it a chore and it feels rewarding to not have to do it again? Why does the new mechanic have such appeal if we know it too will just be automated away later on, and we'll be happy when that happens? It honestly begs the question of why this framework of introducing content and automating the old content is even enjoyable - and nearly nonexistent in other genres. You're not going to reach a point in a platformer game where they just automate the jumping part - that's the core mechanic! Instead, platformers either add new mechanics that build on the core mechanic or at least re-contextualize the core mechanic. However, in incremental games new content very frequently means replacing older content, as opposed to augmenting it.

Admittedly, the above paragraph ignores the obvious answer that separates incremental games in this regard. These mechanics become chores as their frequency increases. The frequency increases to give a sense of progression, and automation is seen as a reward because it now manages what was becoming unmanageable. The new content then comes in and continues the loop to give a stronger sense of progression. That's all good and a fine justification for automating content instead of building upon the base mechanic. It's also much easier to design, as each layer essentially lets you start over instead of needing to think of ideas that conform to the original core mechanic.

So, what's the problem? Even if this trend is justified and easy to implement, there are some other effects it has on the game design. First off, and this is probably a neutral point, incremental games with this cycle of replacing old mechanics with new ones trend towards more and more abstract and further away from any narrative throughline as they add layers. There are only so many justifications for resetting progress, so if a game wants to have several of these layers they're inevitably going to become generic or increasingly loosely associated with the original content. It's most unfortunate, in my opinion when an interesting or innovative core mechanic gets fully automated once a generic "prestige" layer is unlocked.

A recent example is Really Grass Cutting Incremental, an incremental game about cutting grass (although I'm really criticizing the Roblox game it's based on). Except, it doesn't continue to be about cutting grass. After you buy enough upgrades to increase your grass cutting and level up sufficiently you "prestige", an abstract term that in this case means you reset all your progress to get some currency to buy upgrades that do the same things as the original upgrades, but these won't reset on future prestiges. You'll eventually be able to "crystallize", which means you reset all your progress to get some currency to buy upgrades that do the same things as the original upgrades (and a couple of new ones) and won't reset on future crystallizes. Fine. You'll progress a bit, complete some challenges, and finally get to... grasshop? Grasshopping is this mechanic where you reset all your progress to get some resource that isn't for buying upgrades - this time you just unlock different modifiers on everything based on their amount. You may have gotten the point by now, but there are also "steelie" resets which give you steel for some reason, before unlocking a factory with various machines - none of which are directly tied to cutting grass, and start gathering things like oil and reset for rocket parts and reset to go to space and so on and so on. Throughout all of this there is absolutely no narrative justification or throughline for the direction the game is going, or why cutting grass is still relevant when we're collecting things like rocket parts. I may be going a little hard on GCI, but it is far from alone.

Ending the Game

Incremental games do not often have a planned out narrative or ending,, such that each content update is approached as its own unit of narrative and gameplay. This prevents content updates from wrapping up the game nicely - it always has to leave something open for another content layer; be it another mechanic, reset layer, etc. This cycle will continue until the updates just stop, at which point the game will just have an unsatisfying conclusion that will never get the next thing it was supposed to be leading into. This reminds me of a Leonardo Da Vinci quote about how Art is Never Complete:

Art is never finished, only abandoned. - Leonardo Da Vinci

For what its worth, there are exceptions here (including several of My Projects). I believe this practice is actually fairly reasonable, considering how many incremental game developers are learning game design and programming - keeping the scope small and expanding if it still interests you is a great way to keep learning without letting things like perfectionism or sunk cost fallacies get in the way.

Tips for Developers

If you're a developer, by this point you should have a pretty decent idea of how to create "true" content in your game. Here are some other specific tips I'd suggest:

An upgrade that simply unlocks another upgrade trivially isn't content. However, many games have an upgrade that just unlocks a feature, which then has a wait or other requirements before it can be used. Try to make sure when you unlock a feature, there is immediately something to do with the feature - for example, perhaps give them a small amount of the new currency it unlocks, if applicable.

If you don't have a large web of effects, and can definitively say the impact of a purchase is to multiply the gain of the cost currency by N, and the next purchase costs N times the amount of that same currency, then this purchase effectively made no difference and it may have made more sense to just go directly to the next upgrade. That said, having effects based on things like the number of purchases made will quickly invalidate this tip.

',29),b=JSON.parse('{"title":"Guide to Incrementals/What is Content?","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/what-is-content-","title":"Guide to Incrementals/What is Content?","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/ludology/content/index.md","filePath":"guide-to-incrementals/ludology/content/index.md"}'),m={name:"guide-to-incrementals/ludology/content/index.md"},w=Object.assign(m,{setup(d){const a=o();return(g,p)=>(h(),i("div",null,[l,e("p",null,[s("2272 words, ~12 minute read. "),e("span",{innerHTML:t(n)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),u]))}});export{b as __pageData,w as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as i,Q as e,K as s,u as t,ag as r,p as h}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Guide to Incrementals/What is Content?",-1),c=["innerHTML"],u=r('
Referenced by:Incremental SocialKronos

If you've been in the incremental games community for any amount of time, you'll quickly find the number one thing players want is content. They want as much of it as possible! The most popular incremental games have tons of content, so they just keep stretching on and on and on, introducing mechanic after mechanic, and players love it. In fact, players seem to value the amount of content over the quality of any specific content. However, there's a bit of a lack of understanding concerning what content is, and I'd like to explore what counts as content, and how we measure it. As a baseline definition, I think "content" can just be described as the parts of the game that engage the player, but to truly understand it we need to contextualize what that means and how it affects the gameplay experience.

To clarify the purpose of this page, my goal is not to get (too) nitpicky or to attack games with "low content". There's nothing wrong with short / low-content games - I'm quite a big fan of those games myself! This is mostly targeted toward those who ask for content and settle for "long" games, and those who want to provide content but want to make sure they're not just artificially inflating the game. Ultimately, I suppose the goal is to just reduce the amount of artificially inflated content for the sake of having a "longer" game.

Interaction

I think it should be a fairly non-controversial opinion that time spent solely waiting should not count towards content. That is not including the time reading various effects or making decisions in your head, but rather time spent waiting for a condition to be met so you can re-engage with the game.

That is not to say games should necessarily try to minimize this time. Plenty of games lead towards more infrequent interaction and still get popular. In fact, these games appeal to many gamers who want to have something to check up on in between bursts of working on some other activity. These games seem to have fallen slightly out of fashion amongst modern incremental games, but they're still fully valid. The point I'm trying to make here is just that this time is not content. As an extreme example, a game with no interactions and just a counter that goes up every second could safely be said to have 0 content beyond the time it takes to understand what's going on. If it has a list of "goals" to hit, then the time understanding those goals and a short time after achieving each one could be considered content, but not the idle times in between.

Let's take a look at the opposite end of the spectrum - interaction that is so frequent as to become mindless. This is any mechanic where you need to spam-click something to progress. This may be a more controversial take, but I do not believe this constitutes content either. It does not engage the player, because each consecutive click blends together and they do not individually change the gameplay experience. That is to say, a single click and 100 clicks are not meaningfully different in terms of engaging the player. I'd go as far as to say clicking 100 times would be actively worse, as it's artificially delaying the next piece of actual content, alongside the issues of accessibility and potentially causing RSI.

Repeatable Purchases

Imagine an entity in a game that you can purchase multiple times, each time it performs the same thing but for a higher cost. These are incredibly common, from the buildings in cookie clicker to the units in swarm sim to the IP and EP multipliers in antimatter dimensions. However, how much content is each specific purchase? Is it content beyond the first purchase? Does it have diminishing returns? What if you are oscillating between two different repeatable purchases? How much content is lost when you automate) away a repeatable purchase?

I don't want to take too harsh a stance against repeatable purchases. They're useful tools and can be used in a myriad of interesting ways. I feel they do become "stale" or less meaningful content over time, and this happens exponentially quickly the more frequently it can be purchased. A classic example that I believe goes too far is the IP/EP multipliers in Antimatter Dimensions. I would go as far as to say they are a chore and do not provide any meaningful content after you've bought them a couple of times. It's a method for inflating numbers (effectively making every OOM a 5x step instead of 10x), that punishes the player progression-wise whenever they forget to max it again, and eventually gets automated away as a reward to the player for making enough progress.

Just to voice the other side of this argument, Acamaeda defended the IP multiplier as giving the player a "good" upgrade every OOM. I can understand that to a point and need to clarify I'm mainly criticizing IP/EP multipliers after they've been introduced for a while. In fact, I would defend the multipliers for a short while after they're introduced using the same logic I would use to defend normal dimensions as repeatable purchases, at least pre-infinity. There's "content" to be had in looking at what dimensions will become affordable next, and then choosing which to buy amongst those. The IP/EP multipliers, early into infinity or eternity respectively, provide another option that gets put into that mental queue of things to buy with each OOM reached - although the optimal order is often quite trivial and not particularly engaging.

The IP/EP multipliers are not the only repeatable purchase in antimatter dimensions I take offense to. The time dimensions are also a series of repeatable purchases, that are all so similar and static that it doesn't take long before you never need to put any thought into buying them, how much you're buying at once, or the order you buy them in - you just press max all and move on. The entire tab could've been just the max all button and it would not have made a difference beyond the start of the eternity layer. The normal dimensions technically have this problem as well, but since you're constantly getting antimatter the order feels like it has a larger impact and it's more meaningful content, right up until they're automated away. Infinity dimensions are a compromise between the two, so I'm highlighting time dimensions here as the most egregious.

Following Instructions

We're getting more and more controversial as we go along! Let's talk about how linear content is not content now (in some circumstances). A trend in incremental games is adding difficulty by adding a web of effects that abstract the true change you can expect from any specific purchase or decision you make. If a game is both linear and sufficiently abstracts the effect of player decisions, then the player will no longer be engaging with the content - they'll simply be clicking on things as they become available. This isn't necessarily a bad thing, as plenty of players don't mind this style of gameplay, but I'd argue once you reach a point where players don't bother reading the effects, those interactions are no longer truly content. Note that unlike the previous qualifiers mentioned, this qualifier is based on the player, and therefore subjective. In effect, it's a spectrum where the more complicated the web of effects becomes, the more likely it is to disengage the player.

This over-complicatedness leading to disengaging the player can also happen from non-linear gameplay. If the web of effects becomes sufficiently complicated and finding the optimal progression route too time-consuming to discover, players will seek out guides from other players who've completed the game. The second they do this, the game effectively becomes linearly following the instructions of the guide and all the above criticisms apply. Similarly to as before, though, this is a spectrum and not everyone will seek out a guide at the same level of difficulty.

Automation

Automation is a staple of the genre, but it has certain implications for the design of the game. Why, when new content is introduced, must the older content be automated away - why is it a chore and it feels rewarding to not have to do it again? Why does the new mechanic have such appeal if we know it too will just be automated away later on, and we'll be happy when that happens? It honestly begs the question of why this framework of introducing content and automating the old content is even enjoyable - and nearly nonexistent in other genres. You're not going to reach a point in a platformer game where they just automate the jumping part - that's the core mechanic! Instead, platformers either add new mechanics that build on the core mechanic or at least re-contextualize the core mechanic. However, in incremental games new content very frequently means replacing older content, as opposed to augmenting it.

Admittedly, the above paragraph ignores the obvious answer that separates incremental games in this regard. These mechanics become chores as their frequency increases. The frequency increases to give a sense of progression, and automation is seen as a reward because it now manages what was becoming unmanageable. The new content then comes in and continues the loop to give a stronger sense of progression. That's all good and a fine justification for automating content instead of building upon the base mechanic. It's also much easier to design, as each layer essentially lets you start over instead of needing to think of ideas that conform to the original core mechanic.

So, what's the problem? Even if this trend is justified and easy to implement, there are some other effects it has on the game design. First off, and this is probably a neutral point, incremental games with this cycle of replacing old mechanics with new ones trend towards more and more abstract and further away from any narrative throughline as they add layers. There are only so many justifications for resetting progress, so if a game wants to have several of these layers they're inevitably going to become generic or increasingly loosely associated with the original content. It's most unfortunate, in my opinion when an interesting or innovative core mechanic gets fully automated once a generic "prestige" layer is unlocked.

A recent example is Really Grass Cutting Incremental, an incremental game about cutting grass (although I'm really criticizing the Roblox game it's based on). Except, it doesn't continue to be about cutting grass. After you buy enough upgrades to increase your grass cutting and level up sufficiently you "prestige", an abstract term that in this case means you reset all your progress to get some currency to buy upgrades that do the same things as the original upgrades, but these won't reset on future prestiges. You'll eventually be able to "crystallize", which means you reset all your progress to get some currency to buy upgrades that do the same things as the original upgrades (and a couple of new ones) and won't reset on future crystallizes. Fine. You'll progress a bit, complete some challenges, and finally get to... grasshop? Grasshopping is this mechanic where you reset all your progress to get some resource that isn't for buying upgrades - this time you just unlock different modifiers on everything based on their amount. You may have gotten the point by now, but there are also "steelie" resets which give you steel for some reason, before unlocking a factory with various machines - none of which are directly tied to cutting grass, and start gathering things like oil and reset for rocket parts and reset to go to space and so on and so on. Throughout all of this there is absolutely no narrative justification or throughline for the direction the game is going, or why cutting grass is still relevant when we're collecting things like rocket parts. I may be going a little hard on GCI, but it is far from alone.

Ending the Game

Incremental games do not often have a planned out narrative or ending,, such that each content update is approached as its own unit of narrative and gameplay. This prevents content updates from wrapping up the game nicely - it always has to leave something open for another content layer; be it another mechanic, reset layer, etc. This cycle will continue until the updates just stop, at which point the game will just have an unsatisfying conclusion that will never get the next thing it was supposed to be leading into. This reminds me of a Leonardo Da Vinci quote about how Art is Never Complete:

Art is never finished, only abandoned. - Leonardo Da Vinci

For what its worth, there are exceptions here (including several of My Projects). I believe this practice is actually fairly reasonable, considering how many incremental game developers are learning game design and programming - keeping the scope small and expanding if it still interests you is a great way to keep learning without letting things like perfectionism or sunk cost fallacies get in the way.

Tips for Developers

If you're a developer, by this point you should have a pretty decent idea of how to create "true" content in your game. Here are some other specific tips I'd suggest:

An upgrade that simply unlocks another upgrade trivially isn't content. However, many games have an upgrade that just unlocks a feature, which then has a wait or other requirements before it can be used. Try to make sure when you unlock a feature, there is immediately something to do with the feature - for example, perhaps give them a small amount of the new currency it unlocks, if applicable.

If you don't have a large web of effects, and can definitively say the impact of a purchase is to multiply the gain of the cost currency by N, and the next purchase costs N times the amount of that same currency, then this purchase effectively made no difference and it may have made more sense to just go directly to the next upgrade. That said, having effects based on things like the number of purchases made will quickly invalidate this tip.

',29),b=JSON.parse('{"title":"Guide to Incrementals/What is Content?","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/what-is-content-","title":"Guide to Incrementals/What is Content?","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/ludology/content/index.md","filePath":"guide-to-incrementals/ludology/content/index.md"}'),m={name:"guide-to-incrementals/ludology/content/index.md"},w=Object.assign(m,{setup(d){const a=o();return(g,p)=>(h(),i("div",null,[l,e("p",null,[s("2272 words, ~12 minute read. "),e("span",{innerHTML:t(n)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),u]))}});export{b as __pageData,w as default}; diff --git a/assets/guide-to-incrementals_ludology_content_index.md.BMb_w6x8.lean.js b/assets/guide-to-incrementals_ludology_content_index.md.zhZ55mqj.lean.js similarity index 93% rename from assets/guide-to-incrementals_ludology_content_index.md.BMb_w6x8.lean.js rename to assets/guide-to-incrementals_ludology_content_index.md.zhZ55mqj.lean.js index d141345c5..e27991620 100644 --- a/assets/guide-to-incrementals_ludology_content_index.md.BMb_w6x8.lean.js +++ b/assets/guide-to-incrementals_ludology_content_index.md.zhZ55mqj.lean.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as i,Q as e,K as s,u as t,ag as r,p as h}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Guide to Incrementals/What is Content?",-1),c=["innerHTML"],u=r("",29),b=JSON.parse('{"title":"Guide to Incrementals/What is Content?","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/what-is-content-","title":"Guide to Incrementals/What is Content?","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/ludology/content/index.md","filePath":"guide-to-incrementals/ludology/content/index.md"}'),m={name:"guide-to-incrementals/ludology/content/index.md"},w=Object.assign(m,{setup(d){const a=o();return(g,p)=>(h(),i("div",null,[l,e("p",null,[s("2272 words, ~12 minute read. "),e("span",{innerHTML:t(n)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),u]))}});export{b as __pageData,w as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as i,Q as e,K as s,u as t,ag as r,p as h}from"./chunks/framework.Sr2_9k8k.js";const l=e("h1",{class:"p-name"},"Guide to Incrementals/What is Content?",-1),c=["innerHTML"],u=r("",29),b=JSON.parse('{"title":"Guide to Incrementals/What is Content?","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/what-is-content-","title":"Guide to Incrementals/What is Content?","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/ludology/content/index.md","filePath":"guide-to-incrementals/ludology/content/index.md"}'),m={name:"guide-to-incrementals/ludology/content/index.md"},w=Object.assign(m,{setup(d){const a=o();return(g,p)=>(h(),i("div",null,[l,e("p",null,[s("2272 words, ~12 minute read. "),e("span",{innerHTML:t(n)[`site/${t(a).page.value.relativePath}`]},null,8,c)]),u]))}});export{b as __pageData,w as default}; diff --git a/assets/guide-to-incrementals_ludology_definition_index.md.Cv0KfjdU.js b/assets/guide-to-incrementals_ludology_definition_index.md.CepGvxbT.js similarity index 99% rename from assets/guide-to-incrementals_ludology_definition_index.md.Cv0KfjdU.js rename to assets/guide-to-incrementals_ludology_definition_index.md.CepGvxbT.js index 9760372a5..3d78b98ae 100644 --- a/assets/guide-to-incrementals_ludology_definition_index.md.Cv0KfjdU.js +++ b/assets/guide-to-incrementals_ludology_definition_index.md.CepGvxbT.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as o,Q as e,K as i,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Guide to Incrementals/Defining the Genre",-1),m=["innerHTML"],c=s('
Referenced by:Incremental SocialKronos

Video games are placed into genres for a variety of reasons. They can give a mental shorthand to set the player's expectations up, they can help a game market itself by its similarities to other, already popular games, and honestly, people just love categorization for its own sake. For this guide, it's important to define the genre so it is clear what games it's even talking about.

This poses a problem. Genres, being Social Constructs, suffer from the usual issues social constructs have of being vague and shifting over time. "Incremental", in particular, is a horribly vague way to define games. Most games have numbers going up in some form or another. We need a more specific definition - similar to how "strategy" can't just mean any game with any amount of strategy because that would be most games. What specifically differentiates incremental games from the rest?

"Incremental" implies it's a genre defined by a game mechanic, but all those game mechanics it could imply exist in many other games. Having a skill tree or upgrades doesn't make you incremental, and if a reset mechanic is all it takes then every roguelite would be an incremental as well. So clearly there's more to it than that - what makes an incremental an incremental?

I'd like to go over a couple of popular suggestions I've seen on defining the genre here. I have my personal preferences and will state them here, but I don't think there's a truly perfect answer.

BTW, if this article made you realize discourse around defining genres is actually a really interesting, even fascinating, topic, I recommend this video essay: Who Shot Guybrush Threepwood? | Genre and the Adventure Game.

Disclaimer: I mostly play incremental games on my computer, and my definitions will be heavily biased towards the games I'm familiar with.

Incrementals vs Idlers vs Clickers

Oftentimes people refer to this genre as idle games and/or clicker games. You'll even find a trend of oxymoronic game titles that contain both terms. "Incremental games" is the umbrella term both those terms fall under. However, I'd like to argue that not only is it better to just use the term "incremental games", but calling them "idle games" or "clicker games" is wrong. Almost universally, these terms are used interchangeably to refer to the same kind of game, where you start the game click spamming and eventually automate the process. Frankly, that kind of game deserves neither title, and the genre of incremental games has trended away from ever requiring click spamming, as it's a bad mechanic, anyways.

While these games do span a spectrum of how active it requires you to be, and sorting games by that metric can be useful for those looking for a particular experience, the borders of when an incremental game counts as an "idler" is too blurry for the term to be useful. "Incremental games" may not be a great descriptive term for the genre (hence this many thousands of words long page on defining what the genre even is), but it's strictly better than calling them "idler" or "clicker" games. This guide will always use the term "incremental games" unless quoting someone else, as it is the term you typically see on all modern games in the genre.

Incrementals as Parodies

Let's start with one of the most interesting definitions of incremental games. Incremental games appear to be distilled versions of games or genres, "revealing" the naked game design at the core of these games or genres not unlike how parodies comment upon their source material.

To understand what that means, think of how a casino uses skinner boxes to emotionally manipulate its customers to keep playing, but "dressing" up the skinner box with tons of stimuli to hide that ultimately the goal is to condition you into coming back compulsively. The idea that incremental games are parodies means taking the stance that at some level all games are similarly manipulating you, giving dopamine rewards in a way that manipulates you to keep playing while not necessarily giving you any value or fulfillment. Incremental games, then, are any games that plainly display the skinner box, and the manipulative core of the game, at the forefront of the experience.

While incremental games can be fun and even healthy in certain contexts, they can exacerbate video game addiction more than other genres. If you feel like playing incremental games is taking priority over other things in your life, or manipulating your sleep schedule, it may be prudent to seek help. See r/StopGaming for resources.

This "undressing" tends to go hand in hand with a reduced focus on aesthetics, often just printing the game state directly to the screen as text. This makes incremental games much easier to develop, particularly for those with programming skills but not art skills, but that's a tangent for why Incremental Games Guide to Incrementals/Appeal to Developers.

Before I continue, I'd like to make my stance clear that I love games and incremental games, and do not think they should be considered inherently bad or manipulative with the above logic. Skinner boxes are just a way of manipulating behavior via rewards. The games are still fun - that's the reward! I'd believe the real criticism here is that it is "empty fun", or "empty dopamine", that doesn't offer any additional value or sense of fulfillment. I don't think that's inherently bad in moderation, although it can become a problem if the game is manipulating you for profit-seeking, or if you play the game to the detriment of the other parts of your life.

Another interpretation of incremental games as parodies comes from several mainstream incremental games that are also parodies of capitalism, such as cookie clicker and adventure capitalist. It's a very common framework for incremental games to portray the ever-increasing numbers as an insatiable hunger for resources, like the ones observed within capitalism. Therefore, these games are used as evidence that the genre as a whole is about parody and commentary.

Popular videos on incremental games that portray the genre as parodies are Why Idle games make good satire, and how it was ruined. and Bad Game Design - Clicker Games. You may also be interested in this response to the latter video from a fan of incremental games: BadGood Game Design - Clicker Games.

I think that this definition ultimately ascribes a motive to the genre as a whole that only happens to apply to some of the more mainstream titles. There certainly are incremental games commenting on different things, including the genre itself as in the case of The Prestige Tree Classic, The Ascension Tree, or Omega Layers, but certainly not all. And of course, not all games that comment on something or parody something are incremental games! Additionally, a very large majority of incremental games are mobile games using these manipulative strategies to get players to spend as much money as possible - hell, Adventure Capitalist is ostensibly a critique on capitalism but features microtransactions and gameplay that manipulates you into buying them! These profit-seeking incremental games certainly belong within the genre but are hardly parodies when they too use manipulation to serve their interests. Also, from my own anecdotal experience, those who use this definition seem to do so from a fairly surface-level familiarity with the genre, and often in the context of criticizing the genre or the fans thereof.

Incrementals as NGU

Another broad definition often used is that incremental games are games where the focus of the game is "numbers going up". This definition proposes that other genres simply use increasing numbers as a means to an end, but incremental games uniquely only care about the numbers themselves going up. Put another way, it implies there should be no narrative justification for the numbers going up other than "why shouldn't they be going up?"

While this definition is common because it feels easy to understand, it is difficult to formally define. Often phrases are used to describe games using this framework, such as having an "exaggerated sense of progression" or "big" numbers. These terms are vague and don't demonstrate an actual threshold between non-incrementals and incrementals. Most games have a sense of progression, so when is it "exaggerated"? How big are "big" numbers? Most notably, RPGs that are typically not considered incrementals will often pass this definition.

Additionally, a lot of incrementals tend to have some theme guiding the gameplay, or at least the names of mechanics. This makes the line blurred between when numbers are going up for their own sake versus for a contextual reason. I believe this point is best illustrated that, while most RPGs are not considered incremental games, there is a sub-genre of "incremental RPGs" that typically relates to RPGs that perform combat automatically. This definition of incremental games does not support RPGs and "incremental RPGs" being on distinct sides of the line if the only difference between them is manual vs automatic combat.

Incrementals as Strategies

This is a rarer interpretation, but there are similarities between incremental games and strategy games, implying incrementals might just be a sub-genre of strategy games. By this approach, incremental games would be defined by their relation to strategy games, and how they involve player strategy. Incremental games are often large optimization problems - above all else, the actual gameplay the player is performing is deciding what to do next. The consequences of wrong decisions are typically more lenient in incremental games - such as just not making optimal progress - but they certainly get complex.

So if we accept the premise that incrementals could fall under strategy, we still need to define what makes a strategy game an incremental versus some other strategy sub-genre. This is a bit tricky due to one particular sub-genre of strategy games: Factory Builders.

Factory builders, such as Factorio or Satisfactory, are games about gaining ever increasing resources, optimizing production, and expanding more and more. That... sounds pretty similar, doesn't it? In fact, there's been some debate on whether factory builders would fall under the "incremental" umbrella. I think it's safe to say the two are certainly related, and probably have quite a bit of overlap in playerbase.

Roguelites as Incrementals?

Earlier on, I mentioned reset mechanics shouldn't be used in the definition because that could make all roguelites incrementals... But what if it does? A lot of incrementals can be described as games with a strong sense of progression, often with layers of meta-progression. Roguelites fit that bill to a T. What would make roguelites not incremental? I honestly don't think there's a good explanation here, but many fans of incremental games will state they do believe the two genres to be unrelated, even if there's a significant overlap between their player bases due to having similar appealing traits.

At this point, it'd be appropriate to consider what part of the definition of roguelites precludes them from also being incrementals, but that reveals a new problem: What are roguelites? They're usually defined as rogue_likes with meta-progression, but that just pushes the problem back a step: Incrementals aren't the only genre to have difficulties defining themselves, it seems! Roguelikes are another genre where the community argues over the formal definition of their genre, although that means we can borrow from their process of coming to a consensus, and maybe come across a viable definition for incremental games.

The Berlin Interpretation

By far the most popular way of defining roguelikes is the "Berlin Interpretation", which acknowledged the diversity of games within the genre and argued the definition should not be based on any ideals about what the genre ought to be, but rather defined by "its canon". They argued there are a handful of games that can be used to define the canon for roguelikes, and from those games, a list of factors can be derived to determine a game's "roguelikeness". The more factors a game has, the more of a roguelike it is. This strategy is very lenient, allowing a game to not present any specific factor so long as it shows enough, and accounts for the blurriness of any genre definition by not explicitly stating how many factors a game must have to qualify as a definite roguelike.

I believe this strategy for defining genres can be applied to other genres as well. A handful of games can be argued to be the incremental games canon, and a list of factors derived from them can be used to judge any game based on its "incrementalness". I'll propose such a canon and list of factors here, but by no means should it be considered the end-all-be-all.

Note: The "Temple of the roguelike", an authority within the genre, has since replaced the Berlin Interpretation with a new set of factors here: https://blog.roguetemple.com/what-is-a-traditional-roguelike/

A Modern Incremental Games Canon

Alright, time to get controversial. Up til now, I've been trying my best to stay objective and analytical, but now it's time to start making some opinionated decisions. I've created a list of games I think could be justified in making up a modern incremental games canon.

Before I mention the list, let's establish how I got to this list. First off, I'm really focusing on building a definition of the genre today, so I prefer modern games over traditional ones. A canon of culturally or historically significant titles to the genre would give a different list. Keep in mind the original Berlin interpretation (and the temple's update to it) were trying to define "traditional roguelikes", which is not my objective here. Building a canon that aims to trace the history of the genre is still valid and useful.

I'm also trying to ensure I pick a large breadth of incremental games, so I'm going to approach the list as a list of archetypes, with a single game to represent it but with other titles mentioned as other examples. This approach places each archetype as equally important, even if one only has a couple entries. Besides the impracticality of a canon that just includes every game, it'd be very biased towards games with large modding communities like Cookie Clicker or The Prestige Tree.

With all that behind us, here is a list of games I think could justifiably make up a Modern Incremental Games Canon:

  • Dodecadragons

    This game represents incremental games with many prestige layers that often have rapid resets and automate lower layers as more get unlocked. Other examples could also include The Prestige Tree, Really Grass Cutting Incremental Classic, Distance Incremental, or the massive modding community TPT has. A lot of the games I've personally worked on fall in this group, like Advent Incremental.

  • Evolve Idle

    This game represents incremental games with few prestige layers, very slow resets, and a focus on resource management. Typically involve some sort of worker allocation. Other examples would be Kitten's Game, Shark Game, or Magic Research.

  • (the) Gnorp Apologue

    This game represents incremental games with a central mechanic that gets added to by various other mechanics. All the mechanics remain relevant throughout the game, with different ones contributing most over time. Other examples include Nodebuster and To the Core. A lot of traditional games also fall in this archetype by having characters or buildings you level up, that each contribute additively to gaining the primary resources. These include Cookie Clicker, Clicker Heroes, and Realm Grinder. In a way, that makes the modern titles mentioned in this archetype the spiritual successors of those traditional games, and exemplifies how the genre has changed.

  • Idle Momentum

    This game represents incremental games that include polynomial growth as a central mechanic that is then built upon. Other examples include Antimatter Dimensions, Swarm Simulator, and Derivative Clicker.

  • Melvor Idle

    This game represents incremental games that are essentially a genre blend between incremental games and RPGs. Compared to other types of RPGs, these games have a focus on progressing while idle. Other examples would be IdleOn and a very large amount of mobile RPGs.

  • Stuck in Time

    This game represents incremental games that include a reset mechanic where there are pre-defined decisions being made during the course of the run. There's typically a concept of a playable character, whose actions are being "queued up" during a run, and these runs become longer or otherwise more productive as the game progresses. There are a lot of examples of this genre, including Cavernous II, Increlution, Progress Knight, Idle Loops, and Groundhog Life.

  • Universal Paperclips

    This game represents incremental games that involve several phases of completely distinct gameplay that fully replace the previous, called "paradigm shifts". Prestige layers are also often paradigm shifts, but this game represents paradigm shifts that are not reset mechanics but still transform the gameplay. Other examples would be Crank or A Dark Room. Spore would be an example that's not typically considered an incremental.

  • Unnamed Space Idle

    This game represents incremental games that focus on unlocking many different independent progression systems that boost each other, and all remain relevant throughout the course of the game. Other examples include NGU Idle, Anti-Idle, Idle Skilling, and Idle Wizard.

It may look like I've just shifted the problem down a level - rather than defining the genre, I'm now defining a bunch of sub-genres. However, the methods used here for defining the canon, and my attempt at ensuring a breadth of games by determining distinct archetypes, is just my approach. This list is additionally biased towards games I'm more familiar with, which will differ person to person. The only hard and fast rule is that every game on the list should be nearly universally accepted as an incremental game. So long as you do that, the factors should be relatively similar, although ofc individuals will still likely have small differences, as is the nature of socially constructed definitions.

Naturally this canon is a perpetual work-in-progress. I'm currently a bit uncertain about the distinctions between the evolve idle, melvor idle, and unnamed space idle archetypes. I could see those being rewritten as two or even a single archetype.

Unfolding

There are several related concepts mentioned in the canon - unfolding, prestige layers, and paradigm shifts. Unfolding is the umbrella term which includes the other two, and is clearly the highest possible value factor for an incremental. It's so common that for a while people referred to incrementals that exhibit this trait as "unfolding" games, to the point of trying to replace the term incremental due to their popularity.

There are many reasons for the appeal of unfolding mechanics. Oftentimes each mechanic builds on top of the existing mechanics, increasing the complexity of the game in steps so the player can follow along. In fact, sometimes the older mechanics will be entirely phased out (e.g. by automating them), so the complexity of the game remains roughly equal throughout the game. In any case, adding new mechanics regularly provides a sense of mystery, with the player anticipating what will happen next. They shake up the gameplay before it gets too stale - allowing the game to entertain for longer before the sense of Guide to Incrementals/What is Content? dissipates. Of the canon games selected above, I would argue every single one contains unfolding to some degree.

I should take a moment to say that while I'm hyping up this specific factor, we cannot just reduce the genre definition to "does it introduce new mechanics over time". Many games have paradigm shifts that are not incremental, so it's just an indicator of incrementalness. Every single canon game may show that it's common amongst incremental games, but could just as easily indicate that they're common in games in general.

High-Value Factors

I won't take as long to discuss the high and low-value factors, as you've already seen most of them brought up earlier on this page. As a reminder, a game does NOT need all of these to be an incremental game, but these are factors that each indicate a strong possibility the game is an incremental, so having several of these means they probably are. These factors apply to most of the canon incremental games.

"Pure UI" Display. Incrementals typically have a data-driven interface of the game state - there isn't a visual representation of the entities within the game. The interface resembles what might be a control panel in another genre, with a focus on numbers, buttons, and readouts rather than animated sprites or scenes. Even when there are visual elements, like item icons or simple enemy images, the player's main interaction is with non-diegetic, UI-focused components rather than immersive game visuals.

Reduced Consequences. Incrementals tend to have reduced repurcussions for misplaying. They very rarely have fail states, where often the largest consequence is simply not progressing - never losing progress.

Optimization Problems. The predominant gameplay of incrementals is typically solving optimization problems, from deciding which purchase to save up for to reasoning and deciding between different mutually exclusive options the game presents.

Resource Management. Incrementals tend to have a lot of resources within the game to keep track of.

Low-Value Factors

These are low-value factors, meaning they aren't as strongly correlated with incremental games. Incremental games may have none of these, and non-incrementals may have several of these - if a game only has low-value factors, they're probably not an incremental.

Fast Numeric Growth. Numbers in incremental games tend to grow faster than in other genres. There are more instances of superlinear growth. The larger the numbers get, the stronger of a signal this factor is.

Automation. As an incremental game progresses, the player often no longer has to deal with earlier mechanics, by having them either happen automatically or otherwise be replaced with an alternative that requires less player interaction.

Goal-Oriented. Incrementals are often heavily reliant on extrinsic motivation to guide the player. Typically this is through some sort of in-game goal to work towards, such as a certain amount of a resource being required to unlock or purchase something new.

Waiting is a Mechanic. In incremental games, the player may come across times where there is no action they can take, and the game will progress automatically instead. The player must wait for some amount of this automatic progress to occur before they can resume interaction with the game.

Are Roguelites Incrementals?

Having made our variation of the Berlin Interpretation for incremental games, we can compare it to the Berlin Interpretation to determine if there's enough overlap that any game that "passes" the Berlin Interpretation would also pass the incremental variant. That is to say, whether any roguelite would also be considered an incremental game.

The meta-progression of an incremental game could arguably be considered a paradigm shift, and certainly adds some resource management. Goal-oriented would probably also apply. I think anything other than those would be a stretch, and in my opinion that just isn't enough to qualify. To be totally honest, I was never expecting to conclude otherwise though 😉

Sub-Genres

There are some trends in incremental games that go beyond just being a commonly used mechanic, such that they deeply affect the rest of the game design. To a degree each of the games in the canon could arguably be part of distinct sub-genres, but I think these 4 deserve specific mentions:

Loops games are a sub-genre defined by having a core mechanic related to a loop, where the player is deciding the actions taken per loop. Notable examples include Idle Loops, Stuck in Time, Cavernous II, and Increlution. You may also argue Groundhog Life and Progress Knight fall into this sub-genre.

ITRTG-like games are a sub-genre defined by having a core mechanic based on clearing increasingly difficult battles and often tend to have a lot of different mechanics to become progressively stronger. Notable examples include Idling to Rule the Gods, NGU Idle, and Wizard and Minion Idle.

Polynomial Growth games are a sub-genre defined by having a core mechanic related to a higher degree polynomial. Notable examples include the base layer of Antimatter Dimensions and Swarm Simulator.

Upgrades Games is a category popular on flash games websites that featured games focused on buying upgrades that would allow you to attain more currency in some sort of minigame that would earn you more money to buy more upgrades, which I'd argue now belong under the fold of incremental games. Notable examples include the Learn to Fly series and Upgrade Complete.

Cultivation RPGs are a genre of games, books, and anime popular in China that center around being in a fantasy world with characters getting stronger over time. While few of them get translated into English, a fan of incremental games may find the available games interesting.

',70),y=JSON.parse('{"title":"Guide to Incrementals/Defining the Genre","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/defining-the-genre","title":"Guide to Incrementals/Defining the Genre","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/ludology/definition/index.md","filePath":"guide-to-incrementals/ludology/definition/index.md"}'),g={name:"guide-to-incrementals/ludology/definition/index.md"},w=Object.assign(g,{setup(d){const a=n();return(u,p)=>(l(),o("div",null,[h,e("p",null,[i("4048 words, ~22 minute read. "),e("span",{innerHTML:t(r)[`site/${t(a).page.value.relativePath}`]},null,8,m)]),c]))}});export{y as __pageData,w as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as o,Q as e,K as i,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Guide to Incrementals/Defining the Genre",-1),m=["innerHTML"],c=s('
Referenced by:Incremental SocialKronos

Video games are placed into genres for a variety of reasons. They can give a mental shorthand to set the player's expectations up, they can help a game market itself by its similarities to other, already popular games, and honestly, people just love categorization for its own sake. For this guide, it's important to define the genre so it is clear what games it's even talking about.

This poses a problem. Genres, being Social Constructs, suffer from the usual issues social constructs have of being vague and shifting over time. "Incremental", in particular, is a horribly vague way to define games. Most games have numbers going up in some form or another. We need a more specific definition - similar to how "strategy" can't just mean any game with any amount of strategy because that would be most games. What specifically differentiates incremental games from the rest?

"Incremental" implies it's a genre defined by a game mechanic, but all those game mechanics it could imply exist in many other games. Having a skill tree or upgrades doesn't make you incremental, and if a reset mechanic is all it takes then every roguelite would be an incremental as well. So clearly there's more to it than that - what makes an incremental an incremental?

I'd like to go over a couple of popular suggestions I've seen on defining the genre here. I have my personal preferences and will state them here, but I don't think there's a truly perfect answer.

BTW, if this article made you realize discourse around defining genres is actually a really interesting, even fascinating, topic, I recommend this video essay: Who Shot Guybrush Threepwood? | Genre and the Adventure Game.

Disclaimer: I mostly play incremental games on my computer, and my definitions will be heavily biased towards the games I'm familiar with.

Incrementals vs Idlers vs Clickers

Oftentimes people refer to this genre as idle games and/or clicker games. You'll even find a trend of oxymoronic game titles that contain both terms. "Incremental games" is the umbrella term both those terms fall under. However, I'd like to argue that not only is it better to just use the term "incremental games", but calling them "idle games" or "clicker games" is wrong. Almost universally, these terms are used interchangeably to refer to the same kind of game, where you start the game click spamming and eventually automate the process. Frankly, that kind of game deserves neither title, and the genre of incremental games has trended away from ever requiring click spamming, as it's a bad mechanic, anyways.

While these games do span a spectrum of how active it requires you to be, and sorting games by that metric can be useful for those looking for a particular experience, the borders of when an incremental game counts as an "idler" is too blurry for the term to be useful. "Incremental games" may not be a great descriptive term for the genre (hence this many thousands of words long page on defining what the genre even is), but it's strictly better than calling them "idler" or "clicker" games. This guide will always use the term "incremental games" unless quoting someone else, as it is the term you typically see on all modern games in the genre.

Incrementals as Parodies

Let's start with one of the most interesting definitions of incremental games. Incremental games appear to be distilled versions of games or genres, "revealing" the naked game design at the core of these games or genres not unlike how parodies comment upon their source material.

To understand what that means, think of how a casino uses skinner boxes to emotionally manipulate its customers to keep playing, but "dressing" up the skinner box with tons of stimuli to hide that ultimately the goal is to condition you into coming back compulsively. The idea that incremental games are parodies means taking the stance that at some level all games are similarly manipulating you, giving dopamine rewards in a way that manipulates you to keep playing while not necessarily giving you any value or fulfillment. Incremental games, then, are any games that plainly display the skinner box, and the manipulative core of the game, at the forefront of the experience.

While incremental games can be fun and even healthy in certain contexts, they can exacerbate video game addiction more than other genres. If you feel like playing incremental games is taking priority over other things in your life, or manipulating your sleep schedule, it may be prudent to seek help. See r/StopGaming for resources.

This "undressing" tends to go hand in hand with a reduced focus on aesthetics, often just printing the game state directly to the screen as text. This makes incremental games much easier to develop, particularly for those with programming skills but not art skills, but that's a tangent for why Incremental Games Guide to Incrementals/Appeal to Developers.

Before I continue, I'd like to make my stance clear that I love games and incremental games, and do not think they should be considered inherently bad or manipulative with the above logic. Skinner boxes are just a way of manipulating behavior via rewards. The games are still fun - that's the reward! I'd believe the real criticism here is that it is "empty fun", or "empty dopamine", that doesn't offer any additional value or sense of fulfillment. I don't think that's inherently bad in moderation, although it can become a problem if the game is manipulating you for profit-seeking, or if you play the game to the detriment of the other parts of your life.

Another interpretation of incremental games as parodies comes from several mainstream incremental games that are also parodies of capitalism, such as cookie clicker and adventure capitalist. It's a very common framework for incremental games to portray the ever-increasing numbers as an insatiable hunger for resources, like the ones observed within capitalism. Therefore, these games are used as evidence that the genre as a whole is about parody and commentary.

Popular videos on incremental games that portray the genre as parodies are Why Idle games make good satire, and how it was ruined. and Bad Game Design - Clicker Games. You may also be interested in this response to the latter video from a fan of incremental games: BadGood Game Design - Clicker Games.

I think that this definition ultimately ascribes a motive to the genre as a whole that only happens to apply to some of the more mainstream titles. There certainly are incremental games commenting on different things, including the genre itself as in the case of The Prestige Tree Classic, The Ascension Tree, or Omega Layers, but certainly not all. And of course, not all games that comment on something or parody something are incremental games! Additionally, a very large majority of incremental games are mobile games using these manipulative strategies to get players to spend as much money as possible - hell, Adventure Capitalist is ostensibly a critique on capitalism but features microtransactions and gameplay that manipulates you into buying them! These profit-seeking incremental games certainly belong within the genre but are hardly parodies when they too use manipulation to serve their interests. Also, from my own anecdotal experience, those who use this definition seem to do so from a fairly surface-level familiarity with the genre, and often in the context of criticizing the genre or the fans thereof.

Incrementals as NGU

Another broad definition often used is that incremental games are games where the focus of the game is "numbers going up". This definition proposes that other genres simply use increasing numbers as a means to an end, but incremental games uniquely only care about the numbers themselves going up. Put another way, it implies there should be no narrative justification for the numbers going up other than "why shouldn't they be going up?"

While this definition is common because it feels easy to understand, it is difficult to formally define. Often phrases are used to describe games using this framework, such as having an "exaggerated sense of progression" or "big" numbers. These terms are vague and don't demonstrate an actual threshold between non-incrementals and incrementals. Most games have a sense of progression, so when is it "exaggerated"? How big are "big" numbers? Most notably, RPGs that are typically not considered incrementals will often pass this definition.

Additionally, a lot of incrementals tend to have some theme guiding the gameplay, or at least the names of mechanics. This makes the line blurred between when numbers are going up for their own sake versus for a contextual reason. I believe this point is best illustrated that, while most RPGs are not considered incremental games, there is a sub-genre of "incremental RPGs" that typically relates to RPGs that perform combat automatically. This definition of incremental games does not support RPGs and "incremental RPGs" being on distinct sides of the line if the only difference between them is manual vs automatic combat.

Incrementals as Strategies

This is a rarer interpretation, but there are similarities between incremental games and strategy games, implying incrementals might just be a sub-genre of strategy games. By this approach, incremental games would be defined by their relation to strategy games, and how they involve player strategy. Incremental games are often large optimization problems - above all else, the actual gameplay the player is performing is deciding what to do next. The consequences of wrong decisions are typically more lenient in incremental games - such as just not making optimal progress - but they certainly get complex.

So if we accept the premise that incrementals could fall under strategy, we still need to define what makes a strategy game an incremental versus some other strategy sub-genre. This is a bit tricky due to one particular sub-genre of strategy games: Factory Builders.

Factory builders, such as Factorio or Satisfactory, are games about gaining ever increasing resources, optimizing production, and expanding more and more. That... sounds pretty similar, doesn't it? In fact, there's been some debate on whether factory builders would fall under the "incremental" umbrella. I think it's safe to say the two are certainly related, and probably have quite a bit of overlap in playerbase.

Roguelites as Incrementals?

Earlier on, I mentioned reset mechanics shouldn't be used in the definition because that could make all roguelites incrementals... But what if it does? A lot of incrementals can be described as games with a strong sense of progression, often with layers of meta-progression. Roguelites fit that bill to a T. What would make roguelites not incremental? I honestly don't think there's a good explanation here, but many fans of incremental games will state they do believe the two genres to be unrelated, even if there's a significant overlap between their player bases due to having similar appealing traits.

At this point, it'd be appropriate to consider what part of the definition of roguelites precludes them from also being incrementals, but that reveals a new problem: What are roguelites? They're usually defined as rogue_likes with meta-progression, but that just pushes the problem back a step: Incrementals aren't the only genre to have difficulties defining themselves, it seems! Roguelikes are another genre where the community argues over the formal definition of their genre, although that means we can borrow from their process of coming to a consensus, and maybe come across a viable definition for incremental games.

The Berlin Interpretation

By far the most popular way of defining roguelikes is the "Berlin Interpretation", which acknowledged the diversity of games within the genre and argued the definition should not be based on any ideals about what the genre ought to be, but rather defined by "its canon". They argued there are a handful of games that can be used to define the canon for roguelikes, and from those games, a list of factors can be derived to determine a game's "roguelikeness". The more factors a game has, the more of a roguelike it is. This strategy is very lenient, allowing a game to not present any specific factor so long as it shows enough, and accounts for the blurriness of any genre definition by not explicitly stating how many factors a game must have to qualify as a definite roguelike.

I believe this strategy for defining genres can be applied to other genres as well. A handful of games can be argued to be the incremental games canon, and a list of factors derived from them can be used to judge any game based on its "incrementalness". I'll propose such a canon and list of factors here, but by no means should it be considered the end-all-be-all.

Note: The "Temple of the roguelike", an authority within the genre, has since replaced the Berlin Interpretation with a new set of factors here: https://blog.roguetemple.com/what-is-a-traditional-roguelike/

A Modern Incremental Games Canon

Alright, time to get controversial. Up til now, I've been trying my best to stay objective and analytical, but now it's time to start making some opinionated decisions. I've created a list of games I think could be justified in making up a modern incremental games canon.

Before I mention the list, let's establish how I got to this list. First off, I'm really focusing on building a definition of the genre today, so I prefer modern games over traditional ones. A canon of culturally or historically significant titles to the genre would give a different list. Keep in mind the original Berlin interpretation (and the temple's update to it) were trying to define "traditional roguelikes", which is not my objective here. Building a canon that aims to trace the history of the genre is still valid and useful.

I'm also trying to ensure I pick a large breadth of incremental games, so I'm going to approach the list as a list of archetypes, with a single game to represent it but with other titles mentioned as other examples. This approach places each archetype as equally important, even if one only has a couple entries. Besides the impracticality of a canon that just includes every game, it'd be very biased towards games with large modding communities like Cookie Clicker or The Prestige Tree.

With all that behind us, here is a list of games I think could justifiably make up a Modern Incremental Games Canon:

  • Dodecadragons

    This game represents incremental games with many prestige layers that often have rapid resets and automate lower layers as more get unlocked. Other examples could also include The Prestige Tree, Really Grass Cutting Incremental Classic, Distance Incremental, or the massive modding community TPT has. A lot of the games I've personally worked on fall in this group, like Advent Incremental.

  • Evolve Idle

    This game represents incremental games with few prestige layers, very slow resets, and a focus on resource management. Typically involve some sort of worker allocation. Other examples would be Kitten's Game, Shark Game, or Magic Research.

  • (the) Gnorp Apologue

    This game represents incremental games with a central mechanic that gets added to by various other mechanics. All the mechanics remain relevant throughout the game, with different ones contributing most over time. Other examples include Nodebuster and To the Core. A lot of traditional games also fall in this archetype by having characters or buildings you level up, that each contribute additively to gaining the primary resources. These include Cookie Clicker, Clicker Heroes, and Realm Grinder. In a way, that makes the modern titles mentioned in this archetype the spiritual successors of those traditional games, and exemplifies how the genre has changed.

  • Idle Momentum

    This game represents incremental games that include polynomial growth as a central mechanic that is then built upon. Other examples include Antimatter Dimensions, Swarm Simulator, and Derivative Clicker.

  • Melvor Idle

    This game represents incremental games that are essentially a genre blend between incremental games and RPGs. Compared to other types of RPGs, these games have a focus on progressing while idle. Other examples would be IdleOn and a very large amount of mobile RPGs.

  • Stuck in Time

    This game represents incremental games that include a reset mechanic where there are pre-defined decisions being made during the course of the run. There's typically a concept of a playable character, whose actions are being "queued up" during a run, and these runs become longer or otherwise more productive as the game progresses. There are a lot of examples of this genre, including Cavernous II, Increlution, Progress Knight, Idle Loops, and Groundhog Life.

  • Universal Paperclips

    This game represents incremental games that involve several phases of completely distinct gameplay that fully replace the previous, called "paradigm shifts". Prestige layers are also often paradigm shifts, but this game represents paradigm shifts that are not reset mechanics but still transform the gameplay. Other examples would be Crank or A Dark Room. Spore would be an example that's not typically considered an incremental.

  • Unnamed Space Idle

    This game represents incremental games that focus on unlocking many different independent progression systems that boost each other, and all remain relevant throughout the course of the game. Other examples include NGU Idle, Anti-Idle, Idle Skilling, and Idle Wizard.

It may look like I've just shifted the problem down a level - rather than defining the genre, I'm now defining a bunch of sub-genres. However, the methods used here for defining the canon, and my attempt at ensuring a breadth of games by determining distinct archetypes, is just my approach. This list is additionally biased towards games I'm more familiar with, which will differ person to person. The only hard and fast rule is that every game on the list should be nearly universally accepted as an incremental game. So long as you do that, the factors should be relatively similar, although ofc individuals will still likely have small differences, as is the nature of socially constructed definitions.

Naturally this canon is a perpetual work-in-progress. I'm currently a bit uncertain about the distinctions between the evolve idle, melvor idle, and unnamed space idle archetypes. I could see those being rewritten as two or even a single archetype.

Unfolding

There are several related concepts mentioned in the canon - unfolding, prestige layers, and paradigm shifts. Unfolding is the umbrella term which includes the other two, and is clearly the highest possible value factor for an incremental. It's so common that for a while people referred to incrementals that exhibit this trait as "unfolding" games, to the point of trying to replace the term incremental due to their popularity.

There are many reasons for the appeal of unfolding mechanics. Oftentimes each mechanic builds on top of the existing mechanics, increasing the complexity of the game in steps so the player can follow along. In fact, sometimes the older mechanics will be entirely phased out (e.g. by automating them), so the complexity of the game remains roughly equal throughout the game. In any case, adding new mechanics regularly provides a sense of mystery, with the player anticipating what will happen next. They shake up the gameplay before it gets too stale - allowing the game to entertain for longer before the sense of Guide to Incrementals/What is Content? dissipates. Of the canon games selected above, I would argue every single one contains unfolding to some degree.

I should take a moment to say that while I'm hyping up this specific factor, we cannot just reduce the genre definition to "does it introduce new mechanics over time". Many games have paradigm shifts that are not incremental, so it's just an indicator of incrementalness. Every single canon game may show that it's common amongst incremental games, but could just as easily indicate that they're common in games in general.

High-Value Factors

I won't take as long to discuss the high and low-value factors, as you've already seen most of them brought up earlier on this page. As a reminder, a game does NOT need all of these to be an incremental game, but these are factors that each indicate a strong possibility the game is an incremental, so having several of these means they probably are. These factors apply to most of the canon incremental games.

"Pure UI" Display. Incrementals typically have a data-driven interface of the game state - there isn't a visual representation of the entities within the game. The interface resembles what might be a control panel in another genre, with a focus on numbers, buttons, and readouts rather than animated sprites or scenes. Even when there are visual elements, like item icons or simple enemy images, the player's main interaction is with non-diegetic, UI-focused components rather than immersive game visuals.

Reduced Consequences. Incrementals tend to have reduced repurcussions for misplaying. They very rarely have fail states, where often the largest consequence is simply not progressing - never losing progress.

Optimization Problems. The predominant gameplay of incrementals is typically solving optimization problems, from deciding which purchase to save up for to reasoning and deciding between different mutually exclusive options the game presents.

Resource Management. Incrementals tend to have a lot of resources within the game to keep track of.

Low-Value Factors

These are low-value factors, meaning they aren't as strongly correlated with incremental games. Incremental games may have none of these, and non-incrementals may have several of these - if a game only has low-value factors, they're probably not an incremental.

Fast Numeric Growth. Numbers in incremental games tend to grow faster than in other genres. There are more instances of superlinear growth. The larger the numbers get, the stronger of a signal this factor is.

Automation. As an incremental game progresses, the player often no longer has to deal with earlier mechanics, by having them either happen automatically or otherwise be replaced with an alternative that requires less player interaction.

Goal-Oriented. Incrementals are often heavily reliant on extrinsic motivation to guide the player. Typically this is through some sort of in-game goal to work towards, such as a certain amount of a resource being required to unlock or purchase something new.

Waiting is a Mechanic. In incremental games, the player may come across times where there is no action they can take, and the game will progress automatically instead. The player must wait for some amount of this automatic progress to occur before they can resume interaction with the game.

Are Roguelites Incrementals?

Having made our variation of the Berlin Interpretation for incremental games, we can compare it to the Berlin Interpretation to determine if there's enough overlap that any game that "passes" the Berlin Interpretation would also pass the incremental variant. That is to say, whether any roguelite would also be considered an incremental game.

The meta-progression of an incremental game could arguably be considered a paradigm shift, and certainly adds some resource management. Goal-oriented would probably also apply. I think anything other than those would be a stretch, and in my opinion that just isn't enough to qualify. To be totally honest, I was never expecting to conclude otherwise though 😉

Sub-Genres

There are some trends in incremental games that go beyond just being a commonly used mechanic, such that they deeply affect the rest of the game design. To a degree each of the games in the canon could arguably be part of distinct sub-genres, but I think these 4 deserve specific mentions:

Loops games are a sub-genre defined by having a core mechanic related to a loop, where the player is deciding the actions taken per loop. Notable examples include Idle Loops, Stuck in Time, Cavernous II, and Increlution. You may also argue Groundhog Life and Progress Knight fall into this sub-genre.

ITRTG-like games are a sub-genre defined by having a core mechanic based on clearing increasingly difficult battles and often tend to have a lot of different mechanics to become progressively stronger. Notable examples include Idling to Rule the Gods, NGU Idle, and Wizard and Minion Idle.

Polynomial Growth games are a sub-genre defined by having a core mechanic related to a higher degree polynomial. Notable examples include the base layer of Antimatter Dimensions and Swarm Simulator.

Upgrades Games is a category popular on flash games websites that featured games focused on buying upgrades that would allow you to attain more currency in some sort of minigame that would earn you more money to buy more upgrades, which I'd argue now belong under the fold of incremental games. Notable examples include the Learn to Fly series and Upgrade Complete.

Cultivation RPGs are a genre of games, books, and anime popular in China that center around being in a fantasy world with characters getting stronger over time. While few of them get translated into English, a fan of incremental games may find the available games interesting.

',70),y=JSON.parse('{"title":"Guide to Incrementals/Defining the Genre","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/defining-the-genre","title":"Guide to Incrementals/Defining the Genre","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/ludology/definition/index.md","filePath":"guide-to-incrementals/ludology/definition/index.md"}'),g={name:"guide-to-incrementals/ludology/definition/index.md"},w=Object.assign(g,{setup(d){const a=n();return(u,p)=>(l(),o("div",null,[h,e("p",null,[i("4048 words, ~22 minute read. "),e("span",{innerHTML:t(r)[`site/${t(a).page.value.relativePath}`]},null,8,m)]),c]))}});export{y as __pageData,w as default}; diff --git a/assets/guide-to-incrementals_ludology_definition_index.md.Cv0KfjdU.lean.js b/assets/guide-to-incrementals_ludology_definition_index.md.CepGvxbT.lean.js similarity index 93% rename from assets/guide-to-incrementals_ludology_definition_index.md.Cv0KfjdU.lean.js rename to assets/guide-to-incrementals_ludology_definition_index.md.CepGvxbT.lean.js index fb87d47e7..d2ef63abd 100644 --- a/assets/guide-to-incrementals_ludology_definition_index.md.Cv0KfjdU.lean.js +++ b/assets/guide-to-incrementals_ludology_definition_index.md.CepGvxbT.lean.js @@ -1 +1 @@ -import{d as r}from"./chunks/git.data.D-Ga3RhB.js";import{M as n,q as o,Q as e,K as i,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Guide to Incrementals/Defining the Genre",-1),m=["innerHTML"],c=s("",70),y=JSON.parse('{"title":"Guide to Incrementals/Defining the Genre","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/defining-the-genre","title":"Guide to Incrementals/Defining the Genre","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/ludology/definition/index.md","filePath":"guide-to-incrementals/ludology/definition/index.md"}'),g={name:"guide-to-incrementals/ludology/definition/index.md"},w=Object.assign(g,{setup(d){const a=n();return(u,p)=>(l(),o("div",null,[h,e("p",null,[i("4048 words, ~22 minute read. "),e("span",{innerHTML:t(r)[`site/${t(a).page.value.relativePath}`]},null,8,m)]),c]))}});export{y as __pageData,w as default}; +import{d as r}from"./chunks/git.data.BcrWSzMU.js";import{M as n,q as o,Q as e,K as i,u as t,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const h=e("h1",{class:"p-name"},"Guide to Incrementals/Defining the Genre",-1),m=["innerHTML"],c=s("",70),y=JSON.parse('{"title":"Guide to Incrementals/Defining the Genre","description":"","frontmatter":{"public":"true","slug":"guide-to-incrementals/defining-the-genre","title":"Guide to Incrementals/Defining the Genre","prev":false,"next":false},"headers":[],"relativePath":"guide-to-incrementals/ludology/definition/index.md","filePath":"guide-to-incrementals/ludology/definition/index.md"}'),g={name:"guide-to-incrementals/ludology/definition/index.md"},w=Object.assign(g,{setup(d){const a=n();return(u,p)=>(l(),o("div",null,[h,e("p",null,[i("4048 words, ~22 minute read. "),e("span",{innerHTML:t(r)[`site/${t(a).page.value.relativePath}`]},null,8,m)]),c]))}});export{y as __pageData,w as default}; diff --git a/assets/index.md.C1CHMYCi.js b/assets/index.md.CNQn2bLH.js similarity index 99% rename from assets/index.md.C1CHMYCi.js rename to assets/index.md.CNQn2bLH.js index e1ab253f7..3a74128c6 100644 --- a/assets/index.md.C1CHMYCi.js +++ b/assets/index.md.CNQn2bLH.js @@ -1,4 +1,4 @@ -import{k as M,C as a,p as d,q as b,I as o,E as l,u as e,F as C,_ as T,r as U,o as F,m as P,Q as n,aP as O,x as k,D as I,ae as $,R as B,S as H,K as u}from"./chunks/framework.Sr2_9k8k.js";import{r as N,N as g,A as V,K as S,R as A,_ as R,V as E,n as w,t as G}from"./chunks/theme.B2ZVa_Iv.js";const x=` +import{k as M,C as a,p as d,q as b,I as o,E as l,u as e,F as C,_ as T,r as U,o as F,m as P,Q as n,aP as O,x as k,D as I,ae as $,R as B,S as H,K as u}from"./chunks/framework.Sr2_9k8k.js";import{r as N,N as g,A as V,K as S,R as A,_ as R,V as E,n as w,t as G}from"./chunks/theme.DpCaOULF.js";const x=` varying vec2 vUv; void main() { diff --git a/assets/index.md.C1CHMYCi.lean.js b/assets/index.md.CNQn2bLH.lean.js similarity index 99% rename from assets/index.md.C1CHMYCi.lean.js rename to assets/index.md.CNQn2bLH.lean.js index e1ab253f7..3a74128c6 100644 --- a/assets/index.md.C1CHMYCi.lean.js +++ b/assets/index.md.CNQn2bLH.lean.js @@ -1,4 +1,4 @@ -import{k as M,C as a,p as d,q as b,I as o,E as l,u as e,F as C,_ as T,r as U,o as F,m as P,Q as n,aP as O,x as k,D as I,ae as $,R as B,S as H,K as u}from"./chunks/framework.Sr2_9k8k.js";import{r as N,N as g,A as V,K as S,R as A,_ as R,V as E,n as w,t as G}from"./chunks/theme.B2ZVa_Iv.js";const x=` +import{k as M,C as a,p as d,q as b,I as o,E as l,u as e,F as C,_ as T,r as U,o as F,m as P,Q as n,aP as O,x as k,D as I,ae as $,R as B,S as H,K as u}from"./chunks/framework.Sr2_9k8k.js";import{r as N,N as g,A as V,K as S,R as A,_ as R,V as E,n as w,t as G}from"./chunks/theme.DpCaOULF.js";const x=` varying vec2 vUv; void main() { diff --git a/assets/now_index.md.ReRq890H.js b/assets/now_index.md.C9Pm0qfB.js similarity index 97% rename from assets/now_index.md.ReRq890H.js rename to assets/now_index.md.C9Pm0qfB.js index 26f2c2fcd..58daaf58b 100644 --- a/assets/now_index.md.ReRq890H.js +++ b/assets/now_index.md.C9Pm0qfB.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as i,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"/now",-1),d=["innerHTML"],h=s('

This "now page" offers a big picture glimpse into what I’m focused on at this point in my life. What is a now page?

Digital Gardens

I'm building (at least) a mockup for Orchard, an app for message gardening into a Network of Knowledge.

Ultimately, I think this project could have some implications on how this digital garden operates, so I've decided to stop further indieweb integrations like webmentions for now. I'd like to see a server be able to bridge indieweb and agentic fediverse posts, and start using the agentic fediverse posts as my new source of truth.

Incremental Social

I'm running and improving the social media site Incremental Social, along with CardboardEmpress.

I'd like to make it host an iroh node for hosting agentic fediverse content, managing a keypair for each account (with options for migration).

Chromatic Lattice

I'm working on a multiplayer incremental game called Chromatic Lattice . It's still largely in the concept phase, and may even be built on the Agentic Fediverse.

Kronos

I'm working on a long single player narratively driven incremental game called Kronos . This is a very long-term project.

',12),w=JSON.parse('{"title":"/now","description":"","frontmatter":{"public":"true","slug":"now","title":"/now","prev":false,"next":false},"headers":[],"relativePath":"now/index.md","filePath":"now/index.md"}'),m={name:"now/index.md"},b=Object.assign(m,{setup(p){const t=o();return(g,f)=>(l(),i("div",null,[c,e("p",null,[r("186 words, ~1 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),h]))}});export{w as __pageData,b as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as i,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"/now",-1),d=["innerHTML"],h=s('

This "now page" offers a big picture glimpse into what I’m focused on at this point in my life. What is a now page?

Digital Gardens

I'm building (at least) a mockup for Orchard, an app for message gardening into a Network of Knowledge.

Ultimately, I think this project could have some implications on how this digital garden operates, so I've decided to stop further indieweb integrations like webmentions for now. I'd like to see a server be able to bridge indieweb and agentic fediverse posts, and start using the agentic fediverse posts as my new source of truth.

Incremental Social

I'm running and improving the social media site Incremental Social, along with CardboardEmpress.

I'd like to make it host an iroh node for hosting agentic fediverse content, managing a keypair for each account (with options for migration).

Chromatic Lattice

I'm working on a multiplayer incremental game called Chromatic Lattice . It's still largely in the concept phase, and may even be built on the Agentic Fediverse.

Kronos

I'm working on a long single player narratively driven incremental game called Kronos . This is a very long-term project.

',12),w=JSON.parse('{"title":"/now","description":"","frontmatter":{"public":"true","slug":"now","title":"/now","prev":false,"next":false},"headers":[],"relativePath":"now/index.md","filePath":"now/index.md"}'),m={name:"now/index.md"},b=Object.assign(m,{setup(p){const t=o();return(g,f)=>(l(),i("div",null,[c,e("p",null,[r("186 words, ~1 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),h]))}});export{w as __pageData,b as default}; diff --git a/assets/now_index.md.ReRq890H.lean.js b/assets/now_index.md.C9Pm0qfB.lean.js similarity index 90% rename from assets/now_index.md.ReRq890H.lean.js rename to assets/now_index.md.C9Pm0qfB.lean.js index 86da0132e..6e8e81340 100644 --- a/assets/now_index.md.ReRq890H.lean.js +++ b/assets/now_index.md.C9Pm0qfB.lean.js @@ -1 +1 @@ -import{d as n}from"./chunks/git.data.D-Ga3RhB.js";import{M as o,q as i,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"/now",-1),d=["innerHTML"],h=s("",12),w=JSON.parse('{"title":"/now","description":"","frontmatter":{"public":"true","slug":"now","title":"/now","prev":false,"next":false},"headers":[],"relativePath":"now/index.md","filePath":"now/index.md"}'),m={name:"now/index.md"},b=Object.assign(m,{setup(p){const t=o();return(g,f)=>(l(),i("div",null,[c,e("p",null,[r("186 words, ~1 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),h]))}});export{w as __pageData,b as default}; +import{d as n}from"./chunks/git.data.BcrWSzMU.js";import{M as o,q as i,Q as e,K as r,u as a,ag as s,p as l}from"./chunks/framework.Sr2_9k8k.js";const c=e("h1",{class:"p-name"},"/now",-1),d=["innerHTML"],h=s("",12),w=JSON.parse('{"title":"/now","description":"","frontmatter":{"public":"true","slug":"now","title":"/now","prev":false,"next":false},"headers":[],"relativePath":"now/index.md","filePath":"now/index.md"}'),m={name:"now/index.md"},b=Object.assign(m,{setup(p){const t=o();return(g,f)=>(l(),i("div",null,[c,e("p",null,[r("186 words, ~1 minute read. "),e("span",{innerHTML:a(n)[`site/${a(t).page.value.relativePath}`]},null,8,d)]),h]))}});export{w as __pageData,b as default}; diff --git a/assets/style.DE2OHMI3.css b/assets/style.Dyr1wKxP.css similarity index 99% rename from assets/style.DE2OHMI3.css rename to assets/style.Dyr1wKxP.css index e7945982d..1cbf4f8c8 100644 --- a/assets/style.DE2OHMI3.css +++ b/assets/style.Dyr1wKxP.css @@ -1 +1 @@ -:root{--vp-c-white: #ffffff;--vp-c-black: #000000;--vp-c-neutral: var(--vp-c-black);--vp-c-neutral-inverse: var(--vp-c-white)}.dark{--vp-c-neutral: var(--vp-c-white);--vp-c-neutral-inverse: var(--vp-c-black)}:root{--vp-c-gray-1: #dddde3;--vp-c-gray-2: #e4e4e9;--vp-c-gray-3: #ebebef;--vp-c-gray-soft: rgba(142, 150, 170, .14);--vp-c-indigo-1: #3451b2;--vp-c-indigo-2: #3a5ccc;--vp-c-indigo-3: #5672cd;--vp-c-indigo-soft: rgba(100, 108, 255, .14);--vp-c-purple-1: #6f42c1;--vp-c-purple-2: #7e4cc9;--vp-c-purple-3: #8e5cd9;--vp-c-purple-soft: rgba(159, 122, 234, .14);--vp-c-green-1: #18794e;--vp-c-green-2: #299764;--vp-c-green-3: #30a46c;--vp-c-green-soft: rgba(16, 185, 129, .14);--vp-c-yellow-1: #915930;--vp-c-yellow-2: #946300;--vp-c-yellow-3: #9f6a00;--vp-c-yellow-soft: rgba(234, 179, 8, .14);--vp-c-red-1: #b8272c;--vp-c-red-2: #d5393e;--vp-c-red-3: #e0575b;--vp-c-red-soft: rgba(244, 63, 94, .14);--vp-c-sponsor: #db2777}.dark{--vp-c-gray-1: #515c67;--vp-c-gray-2: #414853;--vp-c-gray-3: #32363f;--vp-c-gray-soft: rgba(101, 117, 133, .16);--vp-c-indigo-1: #a8b1ff;--vp-c-indigo-2: #5c73e7;--vp-c-indigo-3: #3e63dd;--vp-c-indigo-soft: rgba(100, 108, 255, .16);--vp-c-purple-1: #c8abfa;--vp-c-purple-2: #a879e6;--vp-c-purple-3: #8e5cd9;--vp-c-purple-soft: rgba(159, 122, 234, .16);--vp-c-green-1: #3dd68c;--vp-c-green-2: #30a46c;--vp-c-green-3: #298459;--vp-c-green-soft: rgba(16, 185, 129, .16);--vp-c-yellow-1: #f9b44e;--vp-c-yellow-2: #da8b17;--vp-c-yellow-3: #a46a0a;--vp-c-yellow-soft: rgba(234, 179, 8, .16);--vp-c-red-1: #f66f81;--vp-c-red-2: #f14158;--vp-c-red-3: #b62a3c;--vp-c-red-soft: rgba(244, 63, 94, .16)}:root{--vp-c-bg: #ffffff;--vp-c-bg-alt: #f6f6f7;--vp-c-bg-elv: #ffffff;--vp-c-bg-soft: #f6f6f7}.dark{--vp-c-bg: #1b1b1f;--vp-c-bg-alt: #161618;--vp-c-bg-elv: #202127;--vp-c-bg-soft: #202127}:root{--vp-c-border: #c2c2c4;--vp-c-divider: #e2e2e3;--vp-c-gutter: #e2e2e3}.dark{--vp-c-border: #3c3f44;--vp-c-divider: #2e2e32;--vp-c-gutter: #000000}:root{--vp-c-text-1: rgba(60, 60, 67);--vp-c-text-2: rgba(60, 60, 67, .78);--vp-c-text-3: rgba(60, 60, 67, .56)}.dark{--vp-c-text-1: rgba(255, 255, 245, .86);--vp-c-text-2: rgba(235, 235, 245, .6);--vp-c-text-3: rgba(235, 235, 245, .38)}:root{--vp-c-default-1: var(--vp-c-gray-1);--vp-c-default-2: var(--vp-c-gray-2);--vp-c-default-3: var(--vp-c-gray-3);--vp-c-default-soft: var(--vp-c-gray-soft);--vp-c-brand-1: var(--vp-c-indigo-1);--vp-c-brand-2: var(--vp-c-indigo-2);--vp-c-brand-3: var(--vp-c-indigo-3);--vp-c-brand-soft: var(--vp-c-indigo-soft);--vp-c-brand: var(--vp-c-brand-1);--vp-c-tip-1: var(--vp-c-brand-1);--vp-c-tip-2: var(--vp-c-brand-2);--vp-c-tip-3: var(--vp-c-brand-3);--vp-c-tip-soft: var(--vp-c-brand-soft);--vp-c-note-1: var(--vp-c-brand-1);--vp-c-note-2: var(--vp-c-brand-2);--vp-c-note-3: var(--vp-c-brand-3);--vp-c-note-soft: var(--vp-c-brand-soft);--vp-c-success-1: var(--vp-c-green-1);--vp-c-success-2: var(--vp-c-green-2);--vp-c-success-3: var(--vp-c-green-3);--vp-c-success-soft: var(--vp-c-green-soft);--vp-c-important-1: var(--vp-c-purple-1);--vp-c-important-2: var(--vp-c-purple-2);--vp-c-important-3: var(--vp-c-purple-3);--vp-c-important-soft: var(--vp-c-purple-soft);--vp-c-warning-1: var(--vp-c-yellow-1);--vp-c-warning-2: var(--vp-c-yellow-2);--vp-c-warning-3: var(--vp-c-yellow-3);--vp-c-warning-soft: var(--vp-c-yellow-soft);--vp-c-danger-1: var(--vp-c-red-1);--vp-c-danger-2: var(--vp-c-red-2);--vp-c-danger-3: var(--vp-c-red-3);--vp-c-danger-soft: var(--vp-c-red-soft);--vp-c-caution-1: var(--vp-c-red-1);--vp-c-caution-2: var(--vp-c-red-2);--vp-c-caution-3: var(--vp-c-red-3);--vp-c-caution-soft: var(--vp-c-red-soft)}:root{--vp-font-family-base: "Inter", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--vp-font-family-mono: ui-monospace, "Menlo", "Monaco", "Consolas", "Liberation Mono", "Courier New", monospace;font-optical-sizing:auto}:root:where(:lang(zh)){--vp-font-family-base: "Punctuation SC", "Inter", ui-sans-serif, system-ui, "PingFang SC", "Noto Sans CJK SC", "Noto Sans SC", "Heiti SC", "Microsoft YaHei", "DengXian", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"}:root{--vp-shadow-1: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 2px rgba(0, 0, 0, .06);--vp-shadow-2: 0 3px 12px rgba(0, 0, 0, .07), 0 1px 4px rgba(0, 0, 0, .07);--vp-shadow-3: 0 12px 32px rgba(0, 0, 0, .1), 0 2px 6px rgba(0, 0, 0, .08);--vp-shadow-4: 0 14px 44px rgba(0, 0, 0, .12), 0 3px 9px rgba(0, 0, 0, .12);--vp-shadow-5: 0 18px 56px rgba(0, 0, 0, .16), 0 4px 12px rgba(0, 0, 0, .16)}:root{--vp-z-index-footer: 10;--vp-z-index-local-nav: 20;--vp-z-index-nav: 30;--vp-z-index-layout-top: 40;--vp-z-index-backdrop: 50;--vp-z-index-sidebar: 60}@media (min-width: 960px){:root{--vp-z-index-sidebar: 25}}:root{--vp-layout-max-width: 1440px}:root{--vp-header-anchor-symbol: "#"}:root{--vp-code-line-height: 1.7;--vp-code-font-size: .875em;--vp-code-color: var(--vp-c-brand-1);--vp-code-link-color: var(--vp-c-brand-1);--vp-code-link-hover-color: var(--vp-c-brand-2);--vp-code-bg: var(--vp-c-default-soft);--vp-code-block-color: var(--vp-c-text-2);--vp-code-block-bg: var(--vp-c-bg-alt);--vp-code-block-divider-color: var(--vp-c-gutter);--vp-code-lang-color: var(--vp-c-text-3);--vp-code-line-highlight-color: var(--vp-c-default-soft);--vp-code-line-number-color: var(--vp-c-text-3);--vp-code-line-diff-add-color: var(--vp-c-success-soft);--vp-code-line-diff-add-symbol-color: var(--vp-c-success-1);--vp-code-line-diff-remove-color: var(--vp-c-danger-soft);--vp-code-line-diff-remove-symbol-color: var(--vp-c-danger-1);--vp-code-line-warning-color: var(--vp-c-warning-soft);--vp-code-line-error-color: var(--vp-c-danger-soft);--vp-code-copy-code-border-color: var(--vp-c-divider);--vp-code-copy-code-bg: var(--vp-c-bg-soft);--vp-code-copy-code-hover-border-color: var(--vp-c-divider);--vp-code-copy-code-hover-bg: var(--vp-c-bg);--vp-code-copy-code-active-text: var(--vp-c-text-2);--vp-code-copy-copied-text-content: "Copied";--vp-code-tab-divider: var(--vp-code-block-divider-color);--vp-code-tab-text-color: var(--vp-c-text-2);--vp-code-tab-bg: var(--vp-code-block-bg);--vp-code-tab-hover-text-color: var(--vp-c-text-1);--vp-code-tab-active-text-color: var(--vp-c-text-1);--vp-code-tab-active-bar-color: var(--vp-c-brand-1)}:root{--vp-button-brand-border: transparent;--vp-button-brand-text: var(--vp-c-white);--vp-button-brand-bg: var(--vp-c-brand-3);--vp-button-brand-hover-border: transparent;--vp-button-brand-hover-text: var(--vp-c-white);--vp-button-brand-hover-bg: var(--vp-c-brand-2);--vp-button-brand-active-border: transparent;--vp-button-brand-active-text: var(--vp-c-white);--vp-button-brand-active-bg: var(--vp-c-brand-1);--vp-button-alt-border: transparent;--vp-button-alt-text: var(--vp-c-text-1);--vp-button-alt-bg: var(--vp-c-default-3);--vp-button-alt-hover-border: transparent;--vp-button-alt-hover-text: var(--vp-c-text-1);--vp-button-alt-hover-bg: var(--vp-c-default-2);--vp-button-alt-active-border: transparent;--vp-button-alt-active-text: var(--vp-c-text-1);--vp-button-alt-active-bg: var(--vp-c-default-1);--vp-button-sponsor-border: var(--vp-c-text-2);--vp-button-sponsor-text: var(--vp-c-text-2);--vp-button-sponsor-bg: transparent;--vp-button-sponsor-hover-border: var(--vp-c-sponsor);--vp-button-sponsor-hover-text: var(--vp-c-sponsor);--vp-button-sponsor-hover-bg: transparent;--vp-button-sponsor-active-border: var(--vp-c-sponsor);--vp-button-sponsor-active-text: var(--vp-c-sponsor);--vp-button-sponsor-active-bg: transparent}:root{--vp-custom-block-font-size: 14px;--vp-custom-block-code-font-size: 13px;--vp-custom-block-info-border: transparent;--vp-custom-block-info-text: var(--vp-c-text-1);--vp-custom-block-info-bg: var(--vp-c-default-soft);--vp-custom-block-info-code-bg: var(--vp-c-default-soft);--vp-custom-block-note-border: transparent;--vp-custom-block-note-text: var(--vp-c-text-1);--vp-custom-block-note-bg: var(--vp-c-default-soft);--vp-custom-block-note-code-bg: var(--vp-c-default-soft);--vp-custom-block-tip-border: transparent;--vp-custom-block-tip-text: var(--vp-c-text-1);--vp-custom-block-tip-bg: var(--vp-c-tip-soft);--vp-custom-block-tip-code-bg: var(--vp-c-tip-soft);--vp-custom-block-important-border: transparent;--vp-custom-block-important-text: var(--vp-c-text-1);--vp-custom-block-important-bg: var(--vp-c-important-soft);--vp-custom-block-important-code-bg: var(--vp-c-important-soft);--vp-custom-block-warning-border: transparent;--vp-custom-block-warning-text: var(--vp-c-text-1);--vp-custom-block-warning-bg: var(--vp-c-warning-soft);--vp-custom-block-warning-code-bg: var(--vp-c-warning-soft);--vp-custom-block-danger-border: transparent;--vp-custom-block-danger-text: var(--vp-c-text-1);--vp-custom-block-danger-bg: var(--vp-c-danger-soft);--vp-custom-block-danger-code-bg: var(--vp-c-danger-soft);--vp-custom-block-caution-border: transparent;--vp-custom-block-caution-text: var(--vp-c-text-1);--vp-custom-block-caution-bg: var(--vp-c-caution-soft);--vp-custom-block-caution-code-bg: var(--vp-c-caution-soft);--vp-custom-block-details-border: var(--vp-custom-block-info-border);--vp-custom-block-details-text: var(--vp-custom-block-info-text);--vp-custom-block-details-bg: var(--vp-custom-block-info-bg);--vp-custom-block-details-code-bg: var(--vp-custom-block-info-code-bg)}:root{--vp-input-border-color: var(--vp-c-border);--vp-input-bg-color: var(--vp-c-bg-alt);--vp-input-switch-bg-color: var(--vp-c-default-soft)}:root{--vp-nav-height: 64px;--vp-nav-bg-color: var(--vp-c-bg);--vp-nav-screen-bg-color: var(--vp-c-bg);--vp-nav-logo-height: 24px}.hide-nav{--vp-nav-height: 0px}.hide-nav .VPSidebar{--vp-nav-height: 22px}:root{--vp-local-nav-bg-color: var(--vp-c-bg)}:root{--vp-sidebar-width: 272px;--vp-sidebar-bg-color: var(--vp-c-bg-alt)}:root{--vp-backdrop-bg-color: rgba(0, 0, 0, .6)}:root{--vp-home-hero-name-color: var(--vp-c-brand-1);--vp-home-hero-name-background: transparent;--vp-home-hero-image-background-image: none;--vp-home-hero-image-filter: none}:root{--vp-badge-info-border: transparent;--vp-badge-info-text: var(--vp-c-text-2);--vp-badge-info-bg: var(--vp-c-default-soft);--vp-badge-tip-border: transparent;--vp-badge-tip-text: var(--vp-c-tip-1);--vp-badge-tip-bg: var(--vp-c-tip-soft);--vp-badge-warning-border: transparent;--vp-badge-warning-text: var(--vp-c-warning-1);--vp-badge-warning-bg: var(--vp-c-warning-soft);--vp-badge-danger-border: transparent;--vp-badge-danger-text: var(--vp-c-danger-1);--vp-badge-danger-bg: var(--vp-c-danger-soft)}:root{--vp-carbon-ads-text-color: var(--vp-c-text-1);--vp-carbon-ads-poweredby-color: var(--vp-c-text-2);--vp-carbon-ads-bg-color: var(--vp-c-bg-soft);--vp-carbon-ads-hover-text-color: var(--vp-c-brand-1);--vp-carbon-ads-hover-poweredby-color: var(--vp-c-text-1)}:root{--vp-local-search-bg: var(--vp-c-bg);--vp-local-search-result-bg: var(--vp-c-bg);--vp-local-search-result-border: var(--vp-c-divider);--vp-local-search-result-selected-bg: var(--vp-c-bg);--vp-local-search-result-selected-border: var(--vp-c-brand-1);--vp-local-search-highlight-bg: var(--vp-c-brand-1);--vp-local-search-highlight-text: var(--vp-c-neutral-inverse)}@media (prefers-reduced-motion: reduce){*,:before,:after{animation-delay:-1ms!important;animation-duration:1ms!important;animation-iteration-count:1!important;background-attachment:initial!important;scroll-behavior:auto!important;transition-duration:0s!important;transition-delay:0s!important}}*,:before,:after{box-sizing:border-box}html{line-height:1.4;font-size:16px;-webkit-text-size-adjust:100%}html.dark{color-scheme:dark}body{margin:0;width:100%;min-width:320px;min-height:100vh;line-height:24px;font-family:var(--vp-font-family-base);font-size:16px;font-weight:400;color:var(--vp-c-text-1);background-color:var(--vp-c-bg);font-synthesis:style;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}main{display:block}h1,h2,h3,h4,h5,h6{margin:0;line-height:24px;font-size:16px;font-weight:400}p{margin:0}strong,b{font-weight:600}a,area,button,[role=button],input,label,select,summary,textarea{touch-action:manipulation}a{color:inherit;text-decoration:inherit}ol,ul{list-style:none;margin:0;padding:0}blockquote{margin:0}pre,code,kbd,samp{font-family:var(--vp-font-family-mono)}img,svg,video,canvas,audio,iframe,embed,object{display:block}figure{margin:0}img,video{max-width:100%;height:auto}button,input,optgroup,select,textarea{border:0;padding:0;line-height:inherit;color:inherit}button{padding:0;font-family:inherit;background-color:transparent;background-image:none}button:enabled,[role=button]:enabled{cursor:pointer}button:focus,button:focus-visible{outline:1px dotted;outline:4px auto -webkit-focus-ring-color}button:focus:not(:focus-visible){outline:none!important}input:focus,textarea:focus,select:focus{outline:none}table{border-collapse:collapse}input{background-color:transparent}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:var(--vp-c-text-3)}input::-ms-input-placeholder,textarea::-ms-input-placeholder{color:var(--vp-c-text-3)}input::placeholder,textarea::placeholder{color:var(--vp-c-text-3)}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}input[type=number]{-moz-appearance:textfield}textarea{resize:vertical}select{-webkit-appearance:none}fieldset{margin:0;padding:0}h1,h2,h3,h4,h5,h6,li,p{overflow-wrap:break-word}vite-error-overlay{z-index:9999}mjx-container{display:inline-block;margin:auto 2px -2px}mjx-container>svg{display:inline-block;margin:auto}[class^=vpi-],[class*=" vpi-"],.vp-icon{width:1em;height:1em}[class^=vpi-].bg,[class*=" vpi-"].bg,.vp-icon.bg{background-size:100% 100%;background-color:transparent}[class^=vpi-]:not(.bg),[class*=" vpi-"]:not(.bg),.vp-icon:not(.bg){-webkit-mask:var(--icon) no-repeat;mask:var(--icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit}.vpi-align-left{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M21 6H3M15 12H3M17 18H3'/%3E%3C/svg%3E")}.vpi-arrow-right,.vpi-arrow-down,.vpi-arrow-left,.vpi-arrow-up{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h14M12 5l7 7-7 7'/%3E%3C/svg%3E")}.vpi-chevron-right,.vpi-chevron-down,.vpi-chevron-left,.vpi-chevron-up{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E")}.vpi-chevron-down,.vpi-arrow-down{transform:rotate(90deg)}.vpi-chevron-left,.vpi-arrow-left{transform:rotate(180deg)}.vpi-chevron-up,.vpi-arrow-up{transform:rotate(-90deg)}.vpi-square-pen{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7'/%3E%3Cpath d='M18.375 2.625a2.121 2.121 0 1 1 3 3L12 15l-4 1 1-4Z'/%3E%3C/svg%3E")}.vpi-plus{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h14M12 5v14'/%3E%3C/svg%3E")}.vpi-sun{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='4'/%3E%3Cpath d='M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41'/%3E%3C/svg%3E")}.vpi-moon{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z'/%3E%3C/svg%3E")}.vpi-more-horizontal{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='1'/%3E%3Ccircle cx='19' cy='12' r='1'/%3E%3Ccircle cx='5' cy='12' r='1'/%3E%3C/svg%3E")}.vpi-languages{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m5 8 6 6M4 14l6-6 2-3M2 5h12M7 2h1M22 22l-5-10-5 10M14 18h6'/%3E%3C/svg%3E")}.vpi-heart{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z'/%3E%3C/svg%3E")}.vpi-search{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E")}.vpi-layout-list{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='7' height='7' x='3' y='3' rx='1'/%3E%3Crect width='7' height='7' x='3' y='14' rx='1'/%3E%3Cpath d='M14 4h7M14 9h7M14 15h7M14 20h7'/%3E%3C/svg%3E")}.vpi-delete{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M20 5H9l-7 7 7 7h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2ZM18 9l-6 6M12 9l6 6'/%3E%3C/svg%3E")}.vpi-corner-down-left{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m9 10-5 5 5 5'/%3E%3Cpath d='M20 4v7a4 4 0 0 1-4 4H4'/%3E%3C/svg%3E")}:root{--vp-icon-copy: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3C/svg%3E");--vp-icon-copied: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3Cpath d='m9 14 2 2 4-4'/%3E%3C/svg%3E")}.vpi-social-discord{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418Z'/%3E%3C/svg%3E")}.vpi-social-facebook{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9.101 23.691v-7.98H6.627v-3.667h2.474v-1.58c0-4.085 1.848-5.978 5.858-5.978.401 0 .955.042 1.468.103a8.68 8.68 0 0 1 1.141.195v3.325a8.623 8.623 0 0 0-.653-.036 26.805 26.805 0 0 0-.733-.009c-.707 0-1.259.096-1.675.309a1.686 1.686 0 0 0-.679.622c-.258.42-.374.995-.374 1.752v1.297h3.919l-.386 2.103-.287 1.564h-3.246v8.245C19.396 23.238 24 18.179 24 12.044c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.628 3.874 10.35 9.101 11.647Z'/%3E%3C/svg%3E")}.vpi-social-github{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")}.vpi-social-instagram{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7.03.084c-1.277.06-2.149.264-2.91.563a5.874 5.874 0 0 0-2.124 1.388 5.878 5.878 0 0 0-1.38 2.127C.321 4.926.12 5.8.064 7.076.008 8.354-.005 8.764.001 12.023c.007 3.259.021 3.667.083 4.947.061 1.277.264 2.149.563 2.911.308.789.72 1.457 1.388 2.123a5.872 5.872 0 0 0 2.129 1.38c.763.295 1.636.496 2.913.552 1.278.056 1.689.069 4.947.063 3.257-.007 3.668-.021 4.947-.082 1.28-.06 2.147-.265 2.91-.563a5.881 5.881 0 0 0 2.123-1.388 5.881 5.881 0 0 0 1.38-2.129c.295-.763.496-1.636.551-2.912.056-1.28.07-1.69.063-4.948-.006-3.258-.02-3.667-.081-4.947-.06-1.28-.264-2.148-.564-2.911a5.892 5.892 0 0 0-1.387-2.123 5.857 5.857 0 0 0-2.128-1.38C19.074.322 18.202.12 16.924.066 15.647.009 15.236-.006 11.977 0 8.718.008 8.31.021 7.03.084m.14 21.693c-1.17-.05-1.805-.245-2.228-.408a3.736 3.736 0 0 1-1.382-.895 3.695 3.695 0 0 1-.9-1.378c-.165-.423-.363-1.058-.417-2.228-.06-1.264-.072-1.644-.08-4.848-.006-3.204.006-3.583.061-4.848.05-1.169.246-1.805.408-2.228.216-.561.477-.96.895-1.382a3.705 3.705 0 0 1 1.379-.9c.423-.165 1.057-.361 2.227-.417 1.265-.06 1.644-.072 4.848-.08 3.203-.006 3.583.006 4.85.062 1.168.05 1.804.244 2.227.408.56.216.96.475 1.382.895.421.42.681.817.9 1.378.165.422.362 1.056.417 2.227.06 1.265.074 1.645.08 4.848.005 3.203-.006 3.583-.061 4.848-.051 1.17-.245 1.805-.408 2.23-.216.56-.477.96-.896 1.38a3.705 3.705 0 0 1-1.378.9c-.422.165-1.058.362-2.226.418-1.266.06-1.645.072-4.85.079-3.204.007-3.582-.006-4.848-.06m9.783-16.192a1.44 1.44 0 1 0 1.437-1.442 1.44 1.44 0 0 0-1.437 1.442M5.839 12.012a6.161 6.161 0 1 0 12.323-.024 6.162 6.162 0 0 0-12.323.024M8 12.008A4 4 0 1 1 12.008 16 4 4 0 0 1 8 12.008'/%3E%3C/svg%3E")}.vpi-social-linkedin{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 0 1-2.063-2.065 2.064 2.064 0 1 1 2.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z'/%3E%3C/svg%3E")}.vpi-social-mastodon{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z'/%3E%3C/svg%3E")}.vpi-social-npm{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M1.763 0C.786 0 0 .786 0 1.763v20.474C0 23.214.786 24 1.763 24h20.474c.977 0 1.763-.786 1.763-1.763V1.763C24 .786 23.214 0 22.237 0zM5.13 5.323l13.837.019-.009 13.836h-3.464l.01-10.382h-3.456L12.04 19.17H5.113z'/%3E%3C/svg%3E")}.vpi-social-slack{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52zm1.271 0a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313zM8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834zm0 1.271a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312zm10.122 2.521a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834zm-1.268 0a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.165 0a2.528 2.528 0 0 1 2.523 2.522v6.312zm-2.523 10.122a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.165 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52zm0-1.268a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.313A2.527 2.527 0 0 1 24 15.165a2.528 2.528 0 0 1-2.522 2.523h-6.313z'/%3E%3C/svg%3E")}.vpi-social-twitter,.vpi-social-x{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z'/%3E%3C/svg%3E")}.vpi-social-youtube{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z'/%3E%3C/svg%3E")}.visually-hidden{position:absolute;width:1px;height:1px;white-space:nowrap;clip:rect(0 0 0 0);clip-path:inset(50%);overflow:hidden}.custom-block{border:1px solid transparent;border-radius:8px;padding:16px 16px 8px;line-height:24px;font-size:var(--vp-custom-block-font-size);color:var(--vp-c-text-2)}.custom-block.info{border-color:var(--vp-custom-block-info-border);color:var(--vp-custom-block-info-text);background-color:var(--vp-custom-block-info-bg)}.custom-block.info a,.custom-block.info code{color:var(--vp-c-brand-1)}.custom-block.info a:hover,.custom-block.info a:hover>code{color:var(--vp-c-brand-2)}.custom-block.info code{background-color:var(--vp-custom-block-info-code-bg)}.custom-block.note{border-color:var(--vp-custom-block-note-border);color:var(--vp-custom-block-note-text);background-color:var(--vp-custom-block-note-bg)}.custom-block.note a,.custom-block.note code{color:var(--vp-c-brand-1)}.custom-block.note a:hover,.custom-block.note a:hover>code{color:var(--vp-c-brand-2)}.custom-block.note code{background-color:var(--vp-custom-block-note-code-bg)}.custom-block.tip{border-color:var(--vp-custom-block-tip-border);color:var(--vp-custom-block-tip-text);background-color:var(--vp-custom-block-tip-bg)}.custom-block.tip a,.custom-block.tip code{color:var(--vp-c-tip-1)}.custom-block.tip a:hover,.custom-block.tip a:hover>code{color:var(--vp-c-tip-2)}.custom-block.tip code{background-color:var(--vp-custom-block-tip-code-bg)}.custom-block.important{border-color:var(--vp-custom-block-important-border);color:var(--vp-custom-block-important-text);background-color:var(--vp-custom-block-important-bg)}.custom-block.important a,.custom-block.important code{color:var(--vp-c-important-1)}.custom-block.important a:hover,.custom-block.important a:hover>code{color:var(--vp-c-important-2)}.custom-block.important code{background-color:var(--vp-custom-block-important-code-bg)}.custom-block.warning{border-color:var(--vp-custom-block-warning-border);color:var(--vp-custom-block-warning-text);background-color:var(--vp-custom-block-warning-bg)}.custom-block.warning a,.custom-block.warning code{color:var(--vp-c-warning-1)}.custom-block.warning a:hover,.custom-block.warning a:hover>code{color:var(--vp-c-warning-2)}.custom-block.warning code{background-color:var(--vp-custom-block-warning-code-bg)}.custom-block.danger{border-color:var(--vp-custom-block-danger-border);color:var(--vp-custom-block-danger-text);background-color:var(--vp-custom-block-danger-bg)}.custom-block.danger a,.custom-block.danger code{color:var(--vp-c-danger-1)}.custom-block.danger a:hover,.custom-block.danger a:hover>code{color:var(--vp-c-danger-2)}.custom-block.danger code{background-color:var(--vp-custom-block-danger-code-bg)}.custom-block.caution{border-color:var(--vp-custom-block-caution-border);color:var(--vp-custom-block-caution-text);background-color:var(--vp-custom-block-caution-bg)}.custom-block.caution a,.custom-block.caution code{color:var(--vp-c-caution-1)}.custom-block.caution a:hover,.custom-block.caution a:hover>code{color:var(--vp-c-caution-2)}.custom-block.caution code{background-color:var(--vp-custom-block-caution-code-bg)}.custom-block.details{border-color:var(--vp-custom-block-details-border);color:var(--vp-custom-block-details-text);background-color:var(--vp-custom-block-details-bg)}.custom-block.details a{color:var(--vp-c-brand-1)}.custom-block.details a:hover,.custom-block.details a:hover>code{color:var(--vp-c-brand-2)}.custom-block.details code{background-color:var(--vp-custom-block-details-code-bg)}.custom-block-title{font-weight:600}.custom-block p+p{margin:8px 0}.custom-block.details summary{margin:0 0 8px;font-weight:700;cursor:pointer;-webkit-user-select:none;user-select:none}.custom-block.details summary+p{margin:8px 0}.custom-block a{color:inherit;font-weight:600;text-decoration:underline;text-underline-offset:2px;transition:opacity .25s}.custom-block a:hover{opacity:.75}.custom-block code{font-size:var(--vp-custom-block-code-font-size)}.custom-block.custom-block th,.custom-block.custom-block blockquote>p{font-size:var(--vp-custom-block-font-size);color:inherit}.dark .vp-code span{color:var(--shiki-dark, inherit)}html:not(.dark) .vp-code span{color:var(--shiki-light, inherit)}.vp-code-group{margin-top:16px}.vp-code-group .tabs{position:relative;display:flex;margin-right:-24px;margin-left:-24px;padding:0 12px;background-color:var(--vp-code-tab-bg);overflow-x:auto;overflow-y:hidden;box-shadow:inset 0 -1px var(--vp-code-tab-divider)}@media (min-width: 640px){.vp-code-group .tabs{margin-right:0;margin-left:0;border-radius:8px 8px 0 0}}.vp-code-group .tabs input{position:fixed;opacity:0;pointer-events:none}.vp-code-group .tabs label{position:relative;display:inline-block;border-bottom:1px solid transparent;padding:0 12px;line-height:48px;font-size:14px;font-weight:500;color:var(--vp-code-tab-text-color);white-space:nowrap;cursor:pointer;transition:color .25s}.vp-code-group .tabs label:after{position:absolute;right:8px;bottom:-1px;left:8px;z-index:1;height:2px;border-radius:2px;content:"";background-color:transparent;transition:background-color .25s}.vp-code-group label:hover{color:var(--vp-code-tab-hover-text-color)}.vp-code-group input:checked+label{color:var(--vp-code-tab-active-text-color)}.vp-code-group input:checked+label:after{background-color:var(--vp-code-tab-active-bar-color)}.vp-code-group div[class*=language-],.vp-block{display:none;margin-top:0!important;border-top-left-radius:0!important;border-top-right-radius:0!important}.vp-code-group div[class*=language-].active,.vp-block.active{display:block}.vp-block{padding:20px 24px}.vp-doc h1,.vp-doc h2,.vp-doc h3,.vp-doc h4,.vp-doc h5,.vp-doc h6{position:relative;font-weight:600;outline:none}.vp-doc h1{letter-spacing:-.02em;line-height:40px;font-size:28px}.vp-doc h2{margin:48px 0 16px;border-top:1px solid var(--vp-c-divider);padding-top:24px;letter-spacing:-.02em;line-height:32px;font-size:24px}.vp-doc h3{margin:32px 0 0;letter-spacing:-.01em;line-height:28px;font-size:20px}.vp-doc .header-anchor{position:absolute;top:0;left:0;margin-left:-.87em;font-weight:500;-webkit-user-select:none;user-select:none;opacity:0;text-decoration:none;transition:color .25s,opacity .25s}.vp-doc .header-anchor:before{content:var(--vp-header-anchor-symbol)}.vp-doc h1:hover .header-anchor,.vp-doc h1 .header-anchor:focus,.vp-doc h2:hover .header-anchor,.vp-doc h2 .header-anchor:focus,.vp-doc h3:hover .header-anchor,.vp-doc h3 .header-anchor:focus,.vp-doc h4:hover .header-anchor,.vp-doc h4 .header-anchor:focus,.vp-doc h5:hover .header-anchor,.vp-doc h5 .header-anchor:focus,.vp-doc h6:hover .header-anchor,.vp-doc h6 .header-anchor:focus{opacity:1}@media (min-width: 768px){.vp-doc h1{letter-spacing:-.02em;line-height:40px;font-size:32px}}.vp-doc h2 .header-anchor{top:24px}.vp-doc p,.vp-doc summary{margin:16px 0}.vp-doc p{line-height:28px}.vp-doc blockquote{margin:16px 0;border-left:2px solid var(--vp-c-divider);padding-left:16px;transition:border-color .5s}.vp-doc blockquote>p{margin:0;font-size:16px;color:var(--vp-c-text-2);transition:color .5s}.vp-doc a{font-weight:500;color:var(--vp-c-brand-1);text-decoration:underline;text-underline-offset:2px;transition:color .25s,opacity .25s}.vp-doc a:hover{color:var(--vp-c-brand-2)}.vp-doc strong{font-weight:600}.vp-doc ul,.vp-doc ol{padding-left:1.25rem;margin:16px 0}.vp-doc ul{list-style:disc}.vp-doc ol{list-style:decimal}.vp-doc li+li{margin-top:8px}.vp-doc li>ol,.vp-doc li>ul{margin:8px 0 0}.vp-doc table{display:block;border-collapse:collapse;margin:20px 0;overflow-x:auto}.vp-doc tr{background-color:var(--vp-c-bg);border-top:1px solid var(--vp-c-divider);transition:background-color .5s}.vp-doc tr:nth-child(2n){background-color:var(--vp-c-bg-soft)}.vp-doc th,.vp-doc td{border:1px solid var(--vp-c-divider);padding:8px 16px}.vp-doc th{text-align:left;font-size:14px;font-weight:600;color:var(--vp-c-text-2);background-color:var(--vp-c-bg-soft)}.vp-doc td{font-size:14px}.vp-doc hr{margin:16px 0;border:none;border-top:1px solid var(--vp-c-divider)}.vp-doc .custom-block{margin:16px 0}.vp-doc .custom-block p{margin:8px 0;line-height:24px}.vp-doc .custom-block p:first-child{margin:0}.vp-doc .custom-block div[class*=language-]{margin:8px 0;border-radius:8px}.vp-doc .custom-block div[class*=language-] code{font-weight:400;background-color:transparent}.vp-doc .custom-block .vp-code-group .tabs{margin:0;border-radius:8px 8px 0 0}.vp-doc :not(pre,h1,h2,h3,h4,h5,h6)>code{font-size:var(--vp-code-font-size);color:var(--vp-code-color)}.vp-doc :not(pre)>code{border-radius:4px;padding:3px 6px;background-color:var(--vp-code-bg);transition:color .25s,background-color .5s}.vp-doc a>code{color:var(--vp-code-link-color)}.vp-doc a:hover>code{color:var(--vp-code-link-hover-color)}.vp-doc h1>code,.vp-doc h2>code,.vp-doc h3>code{font-size:.9em}.vp-doc div[class*=language-],.vp-block{position:relative;margin:16px -24px;background-color:var(--vp-code-block-bg);overflow-x:auto;transition:background-color .5s}@media (min-width: 640px){.vp-doc div[class*=language-],.vp-block{border-radius:8px;margin:16px 0}}@media (max-width: 639px){.vp-doc li div[class*=language-]{border-radius:8px 0 0 8px}}.vp-doc div[class*=language-]+div[class*=language-],.vp-doc div[class$=-api]+div[class*=language-],.vp-doc div[class*=language-]+div[class$=-api]>div[class*=language-]{margin-top:-8px}.vp-doc [class*=language-] pre,.vp-doc [class*=language-] code{direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}.vp-doc [class*=language-] pre{position:relative;z-index:1;margin:0;padding:20px 0;background:transparent;overflow-x:auto}.vp-doc [class*=language-] code{display:block;padding:0 24px;width:fit-content;min-width:100%;line-height:var(--vp-code-line-height);font-size:var(--vp-code-font-size);color:var(--vp-code-block-color);transition:color .5s}.vp-doc [class*=language-] code .highlighted{background-color:var(--vp-code-line-highlight-color);transition:background-color .5s;margin:0 -24px;padding:0 24px;width:calc(100% + 48px);display:inline-block}.vp-doc [class*=language-] code .highlighted.error{background-color:var(--vp-code-line-error-color)}.vp-doc [class*=language-] code .highlighted.warning{background-color:var(--vp-code-line-warning-color)}.vp-doc [class*=language-] code .diff{transition:background-color .5s;margin:0 -24px;padding:0 24px;width:calc(100% + 48px);display:inline-block}.vp-doc [class*=language-] code .diff:before{position:absolute;left:10px}.vp-doc [class*=language-] .has-focused-lines .line:not(.has-focus){filter:blur(.095rem);opacity:.4;transition:filter .35s,opacity .35s}.vp-doc [class*=language-] .has-focused-lines .line:not(.has-focus){opacity:.7;transition:filter .35s,opacity .35s}.vp-doc [class*=language-]:hover .has-focused-lines .line:not(.has-focus){filter:blur(0);opacity:1}.vp-doc [class*=language-] code .diff.remove{background-color:var(--vp-code-line-diff-remove-color);opacity:.7}.vp-doc [class*=language-] code .diff.remove:before{content:"-";color:var(--vp-code-line-diff-remove-symbol-color)}.vp-doc [class*=language-] code .diff.add{background-color:var(--vp-code-line-diff-add-color)}.vp-doc [class*=language-] code .diff.add:before{content:"+";color:var(--vp-code-line-diff-add-symbol-color)}.vp-doc div[class*=language-].line-numbers-mode{padding-left:32px}.vp-doc .line-numbers-wrapper{position:absolute;top:0;bottom:0;left:0;z-index:3;border-right:1px solid var(--vp-code-block-divider-color);padding-top:20px;width:32px;text-align:center;font-family:var(--vp-font-family-mono);line-height:var(--vp-code-line-height);font-size:var(--vp-code-font-size);color:var(--vp-code-line-number-color);transition:border-color .5s,color .5s}.vp-doc [class*=language-]>button.copy{direction:ltr;position:absolute;top:12px;right:12px;z-index:3;border:1px solid var(--vp-code-copy-code-border-color);border-radius:4px;width:40px;height:40px;background-color:var(--vp-code-copy-code-bg);opacity:0;cursor:pointer;background-image:var(--vp-icon-copy);background-position:50%;background-size:20px;background-repeat:no-repeat;transition:border-color .25s,background-color .25s,opacity .25s}.vp-doc [class*=language-]:hover>button.copy,.vp-doc [class*=language-]>button.copy:focus{opacity:1}.vp-doc [class*=language-]>button.copy:hover,.vp-doc [class*=language-]>button.copy.copied{border-color:var(--vp-code-copy-code-hover-border-color);background-color:var(--vp-code-copy-code-hover-bg)}.vp-doc [class*=language-]>button.copy.copied,.vp-doc [class*=language-]>button.copy:hover.copied{border-radius:0 4px 4px 0;background-color:var(--vp-code-copy-code-hover-bg);background-image:var(--vp-icon-copied)}.vp-doc [class*=language-]>button.copy.copied:before,.vp-doc [class*=language-]>button.copy:hover.copied:before{position:relative;top:-1px;transform:translate(calc(-100% - 1px));display:flex;justify-content:center;align-items:center;border:1px solid var(--vp-code-copy-code-hover-border-color);border-right:0;border-radius:4px 0 0 4px;padding:0 10px;width:fit-content;height:40px;text-align:center;font-size:12px;font-weight:500;color:var(--vp-code-copy-code-active-text);background-color:var(--vp-code-copy-code-hover-bg);white-space:nowrap;content:var(--vp-code-copy-copied-text-content)}.vp-doc [class*=language-]>span.lang{position:absolute;top:2px;right:8px;z-index:2;font-size:12px;font-weight:500;color:var(--vp-code-lang-color);transition:color .4s,opacity .4s}.vp-doc [class*=language-]:hover>button.copy+span.lang,.vp-doc [class*=language-]>button.copy:focus+span.lang{opacity:0}.vp-doc .VPTeamMembers{margin-top:24px}.vp-doc .VPTeamMembers.small.count-1 .container{margin:0!important;max-width:calc((100% - 24px)/2)!important}.vp-doc .VPTeamMembers.small.count-2 .container,.vp-doc .VPTeamMembers.small.count-3 .container{max-width:100%!important}.vp-doc .VPTeamMembers.medium.count-1 .container{margin:0!important;max-width:calc((100% - 24px)/2)!important}:is(.vp-external-link-icon,.vp-doc a[href*="://"],.vp-doc a[target=_blank]):not(.no-icon):after{display:inline-block;margin-top:-1px;margin-left:4px;width:11px;height:11px;background:currentColor;color:var(--vp-c-text-3);flex-shrink:0;--icon: url("data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' %3E%3Cpath d='M0 0h24v24H0V0z' fill='none' /%3E%3Cpath d='M9 5v2h6.59L4 18.59 5.41 20 17 8.41V15h2V5H9z' /%3E%3C/svg%3E");-webkit-mask-image:var(--icon);mask-image:var(--icon)}.vp-external-link-icon:after{content:""}.external-link-icon-enabled :is(.vp-doc a[href*="://"],.vp-doc a[target=_blank]):after{content:"";color:currentColor}.vp-sponsor{border-radius:16px;overflow:hidden}.vp-sponsor.aside{border-radius:12px}.vp-sponsor-section+.vp-sponsor-section{margin-top:4px}.vp-sponsor-tier{margin:0 0 4px!important;text-align:center;letter-spacing:1px!important;line-height:24px;width:100%;font-weight:600;color:var(--vp-c-text-2);background-color:var(--vp-c-bg-soft)}.vp-sponsor.normal .vp-sponsor-tier{padding:13px 0 11px;font-size:14px}.vp-sponsor.aside .vp-sponsor-tier{padding:9px 0 7px;font-size:12px}.vp-sponsor-grid+.vp-sponsor-tier{margin-top:4px}.vp-sponsor-grid{display:flex;flex-wrap:wrap;gap:4px}.vp-sponsor-grid.xmini .vp-sponsor-grid-link{height:64px}.vp-sponsor-grid.xmini .vp-sponsor-grid-image{max-width:64px;max-height:22px}.vp-sponsor-grid.mini .vp-sponsor-grid-link{height:72px}.vp-sponsor-grid.mini .vp-sponsor-grid-image{max-width:96px;max-height:24px}.vp-sponsor-grid.small .vp-sponsor-grid-link{height:96px}.vp-sponsor-grid.small .vp-sponsor-grid-image{max-width:96px;max-height:24px}.vp-sponsor-grid.medium .vp-sponsor-grid-link{height:112px}.vp-sponsor-grid.medium .vp-sponsor-grid-image{max-width:120px;max-height:36px}.vp-sponsor-grid.big .vp-sponsor-grid-link{height:184px}.vp-sponsor-grid.big .vp-sponsor-grid-image{max-width:192px;max-height:56px}.vp-sponsor-grid[data-vp-grid="2"] .vp-sponsor-grid-item{width:calc((100% - 4px)/2)}.vp-sponsor-grid[data-vp-grid="3"] .vp-sponsor-grid-item{width:calc((100% - 4px * 2) / 3)}.vp-sponsor-grid[data-vp-grid="4"] .vp-sponsor-grid-item{width:calc((100% - 12px)/4)}.vp-sponsor-grid[data-vp-grid="5"] .vp-sponsor-grid-item{width:calc((100% - 16px)/5)}.vp-sponsor-grid[data-vp-grid="6"] .vp-sponsor-grid-item{width:calc((100% - 4px * 5) / 6)}.vp-sponsor-grid-item{flex-shrink:0;width:100%;background-color:var(--vp-c-bg-soft);transition:background-color .25s}.vp-sponsor-grid-item:hover{background-color:var(--vp-c-default-soft)}.vp-sponsor-grid-item:hover .vp-sponsor-grid-image{filter:grayscale(0) invert(0)}.vp-sponsor-grid-item.empty:hover{background-color:var(--vp-c-bg-soft)}.dark .vp-sponsor-grid-item:hover{background-color:var(--vp-c-white)}.dark .vp-sponsor-grid-item.empty:hover{background-color:var(--vp-c-bg-soft)}.vp-sponsor-grid-link{display:flex}.vp-sponsor-grid-box{display:flex;justify-content:center;align-items:center;width:100%}.vp-sponsor-grid-image{max-width:100%;filter:grayscale(1);transition:filter .25s}.dark .vp-sponsor-grid-image{filter:grayscale(1) invert(1)}.VPBadge{display:inline-block;margin-left:2px;border:1px solid transparent;border-radius:12px;padding:0 10px;line-height:22px;font-size:12px;font-weight:500;transform:translateY(-2px)}.VPBadge.small{padding:0 6px;line-height:18px;font-size:10px;transform:translateY(-8px)}.VPDocFooter .VPBadge{display:none}.vp-doc h1>.VPBadge{margin-top:4px;vertical-align:top}.vp-doc h2>.VPBadge{margin-top:3px;padding:0 8px;vertical-align:top}.vp-doc h3>.VPBadge{vertical-align:middle}.vp-doc h4>.VPBadge,.vp-doc h5>.VPBadge,.vp-doc h6>.VPBadge{vertical-align:middle;line-height:18px}.VPBadge.info{border-color:var(--vp-badge-info-border);color:var(--vp-badge-info-text);background-color:var(--vp-badge-info-bg)}.VPBadge.tip{border-color:var(--vp-badge-tip-border);color:var(--vp-badge-tip-text);background-color:var(--vp-badge-tip-bg)}.VPBadge.warning{border-color:var(--vp-badge-warning-border);color:var(--vp-badge-warning-text);background-color:var(--vp-badge-warning-bg)}.VPBadge.danger{border-color:var(--vp-badge-danger-border);color:var(--vp-badge-danger-text);background-color:var(--vp-badge-danger-bg)}.VPBackdrop[data-v-c79a1216]{position:fixed;top:0;right:0;bottom:0;left:0;z-index:var(--vp-z-index-backdrop);background:var(--vp-backdrop-bg-color);transition:opacity .5s}.VPBackdrop.fade-enter-from[data-v-c79a1216],.VPBackdrop.fade-leave-to[data-v-c79a1216]{opacity:0}.VPBackdrop.fade-leave-active[data-v-c79a1216]{transition-duration:.25s}@media (min-width: 1280px){.VPBackdrop[data-v-c79a1216]{display:none}}.NotFound[data-v-d6be1790]{padding:64px 24px 96px;text-align:center}@media (min-width: 768px){.NotFound[data-v-d6be1790]{padding:96px 32px 168px}}.code[data-v-d6be1790]{line-height:64px;font-size:64px;font-weight:600}.title[data-v-d6be1790]{padding-top:12px;letter-spacing:2px;line-height:20px;font-size:20px;font-weight:700}.divider[data-v-d6be1790]{margin:24px auto 18px;width:64px;height:1px;background-color:var(--vp-c-divider)}.quote[data-v-d6be1790]{margin:0 auto;max-width:256px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.action[data-v-d6be1790]{padding-top:20px}.link[data-v-d6be1790]{display:inline-block;border:1px solid var(--vp-c-brand-1);border-radius:16px;padding:3px 16px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:border-color .25s,color .25s}.link[data-v-d6be1790]:hover{border-color:var(--vp-c-brand-2);color:var(--vp-c-brand-2)}.root[data-v-b933a997]{position:relative;z-index:1}.nested[data-v-b933a997]{padding-right:16px;padding-left:16px}.outline-link[data-v-b933a997]{display:block;line-height:32px;font-size:14px;font-weight:400;color:var(--vp-c-text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .5s}.outline-link[data-v-b933a997]:hover,.outline-link.active[data-v-b933a997]{color:var(--vp-c-text-1);transition:color .25s}.outline-link.nested[data-v-b933a997]{padding-left:13px}.VPDocAsideOutline[data-v-a5bbad30]{display:none}.VPDocAsideOutline.has-outline[data-v-a5bbad30]{display:block}.content[data-v-a5bbad30]{position:relative;border-left:1px solid var(--vp-c-divider);padding-left:16px;font-size:13px;font-weight:500}.outline-marker[data-v-a5bbad30]{position:absolute;top:32px;left:-1px;z-index:0;opacity:0;width:2px;border-radius:2px;height:18px;background-color:var(--vp-c-brand-1);transition:top .25s cubic-bezier(0,1,.5,1),background-color .5s,opacity .25s}.outline-title[data-v-a5bbad30]{line-height:32px;font-size:14px;font-weight:600}.VPDocAside[data-v-3f215769]{display:flex;flex-direction:column;flex-grow:1}.spacer[data-v-3f215769]{flex-grow:1}.VPDocAside[data-v-3f215769] .spacer+.VPDocAsideSponsors,.VPDocAside[data-v-3f215769] .spacer+.VPDocAsideCarbonAds{margin-top:24px}.VPDocAside[data-v-3f215769] .VPDocAsideSponsors+.VPDocAsideCarbonAds{margin-top:16px}.VPLastUpdated[data-v-7e05ebdb]{line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}@media (min-width: 640px){.VPLastUpdated[data-v-7e05ebdb]{line-height:32px;font-size:14px;font-weight:500}}.VPDocFooter[data-v-d4a0bba5]{margin-top:64px}.edit-info[data-v-d4a0bba5]{padding-bottom:18px}@media (min-width: 640px){.edit-info[data-v-d4a0bba5]{display:flex;justify-content:space-between;align-items:center;padding-bottom:14px}}.edit-link-button[data-v-d4a0bba5]{display:flex;align-items:center;border:0;line-height:32px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:color .25s}.edit-link-button[data-v-d4a0bba5]:hover{color:var(--vp-c-brand-2)}.edit-link-icon[data-v-d4a0bba5]{margin-right:8px}.prev-next[data-v-d4a0bba5]{border-top:1px solid var(--vp-c-divider);padding-top:24px;display:grid;grid-row-gap:8px}@media (min-width: 640px){.prev-next[data-v-d4a0bba5]{grid-template-columns:repeat(2,1fr);grid-column-gap:16px}}.pager-link[data-v-d4a0bba5]{display:block;border:1px solid var(--vp-c-divider);border-radius:8px;padding:11px 16px 13px;width:100%;height:100%;transition:border-color .25s}.pager-link[data-v-d4a0bba5]:hover{border-color:var(--vp-c-brand-1)}.pager-link.next[data-v-d4a0bba5]{margin-left:auto;text-align:right}.desc[data-v-d4a0bba5]{display:block;line-height:20px;font-size:12px;font-weight:500;color:var(--vp-c-text-2)}.title[data-v-d4a0bba5]{display:block;line-height:20px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:color .25s}.VPDoc[data-v-39a288b8]{padding:32px 24px 96px;width:100%}@media (min-width: 768px){.VPDoc[data-v-39a288b8]{padding:48px 32px 128px}}@media (min-width: 960px){.VPDoc[data-v-39a288b8]{padding:48px 32px 0}.VPDoc:not(.has-sidebar) .container[data-v-39a288b8]{display:flex;justify-content:center;max-width:992px}.VPDoc:not(.has-sidebar) .content[data-v-39a288b8]{max-width:752px}}@media (min-width: 1280px){.VPDoc .container[data-v-39a288b8]{display:flex;justify-content:center}.VPDoc .aside[data-v-39a288b8]{display:block}}@media (min-width: 1440px){.VPDoc:not(.has-sidebar) .content[data-v-39a288b8]{max-width:784px}.VPDoc:not(.has-sidebar) .container[data-v-39a288b8]{max-width:1104px}}.container[data-v-39a288b8]{margin:0 auto;width:100%}.aside[data-v-39a288b8]{position:relative;display:none;order:2;flex-grow:1;padding-left:32px;width:100%;max-width:256px}.left-aside[data-v-39a288b8]{order:1;padding-left:unset;padding-right:32px}.aside-container[data-v-39a288b8]{position:fixed;top:0;padding-top:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + var(--vp-doc-top-height, 0px) + 48px);width:224px;height:100vh;overflow-x:hidden;overflow-y:auto;scrollbar-width:none}.aside-container[data-v-39a288b8]::-webkit-scrollbar{display:none}.aside-curtain[data-v-39a288b8]{position:fixed;bottom:0;z-index:10;width:224px;height:32px;background:linear-gradient(transparent,var(--vp-c-bg) 70%)}.aside-content[data-v-39a288b8]{display:flex;flex-direction:column;min-height:calc(100vh - (var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px));padding-bottom:32px}.content[data-v-39a288b8]{position:relative;margin:0 auto;width:100%}@media (min-width: 960px){.content[data-v-39a288b8]{padding:0 32px 128px}}@media (min-width: 1280px){.content[data-v-39a288b8]{order:1;margin:0;min-width:640px}}.content-container[data-v-39a288b8]{margin:0 auto}.VPDoc.has-aside .content-container[data-v-39a288b8]{max-width:688px}.VPButton[data-v-cad61b99]{display:inline-block;border:1px solid transparent;text-align:center;font-weight:600;white-space:nowrap;transition:color .25s,border-color .25s,background-color .25s}.VPButton[data-v-cad61b99]:active{transition:color .1s,border-color .1s,background-color .1s}.VPButton.medium[data-v-cad61b99]{border-radius:20px;padding:0 20px;line-height:38px;font-size:14px}.VPButton.big[data-v-cad61b99]{border-radius:24px;padding:0 24px;line-height:46px;font-size:16px}.VPButton.brand[data-v-cad61b99]{border-color:var(--vp-button-brand-border);color:var(--vp-button-brand-text);background-color:var(--vp-button-brand-bg)}.VPButton.brand[data-v-cad61b99]:hover{border-color:var(--vp-button-brand-hover-border);color:var(--vp-button-brand-hover-text);background-color:var(--vp-button-brand-hover-bg)}.VPButton.brand[data-v-cad61b99]:active{border-color:var(--vp-button-brand-active-border);color:var(--vp-button-brand-active-text);background-color:var(--vp-button-brand-active-bg)}.VPButton.alt[data-v-cad61b99]{border-color:var(--vp-button-alt-border);color:var(--vp-button-alt-text);background-color:var(--vp-button-alt-bg)}.VPButton.alt[data-v-cad61b99]:hover{border-color:var(--vp-button-alt-hover-border);color:var(--vp-button-alt-hover-text);background-color:var(--vp-button-alt-hover-bg)}.VPButton.alt[data-v-cad61b99]:active{border-color:var(--vp-button-alt-active-border);color:var(--vp-button-alt-active-text);background-color:var(--vp-button-alt-active-bg)}.VPButton.sponsor[data-v-cad61b99]{border-color:var(--vp-button-sponsor-border);color:var(--vp-button-sponsor-text);background-color:var(--vp-button-sponsor-bg)}.VPButton.sponsor[data-v-cad61b99]:hover{border-color:var(--vp-button-sponsor-hover-border);color:var(--vp-button-sponsor-hover-text);background-color:var(--vp-button-sponsor-hover-bg)}.VPButton.sponsor[data-v-cad61b99]:active{border-color:var(--vp-button-sponsor-active-border);color:var(--vp-button-sponsor-active-text);background-color:var(--vp-button-sponsor-active-bg)}html:not(.dark) .VPImage.dark[data-v-8426fc1a]{display:none}.dark .VPImage.light[data-v-8426fc1a]{display:none}.VPHero[data-v-303bb580]{margin-top:calc((var(--vp-nav-height) + var(--vp-layout-top-height, 0px)) * -1);padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px) 24px 48px}@media (min-width: 640px){.VPHero[data-v-303bb580]{padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 48px 64px}}@media (min-width: 960px){.VPHero[data-v-303bb580]{padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 64px 64px}}.container[data-v-303bb580]{display:flex;flex-direction:column;margin:0 auto;max-width:1152px}@media (min-width: 960px){.container[data-v-303bb580]{flex-direction:row}}.main[data-v-303bb580]{position:relative;z-index:10;order:2;flex-grow:1;flex-shrink:0}.VPHero.has-image .container[data-v-303bb580]{text-align:center}@media (min-width: 960px){.VPHero.has-image .container[data-v-303bb580]{text-align:left}}@media (min-width: 960px){.main[data-v-303bb580]{order:1;width:calc((100% / 3) * 2)}.VPHero.has-image .main[data-v-303bb580]{max-width:592px}}.name[data-v-303bb580],.text[data-v-303bb580]{max-width:392px;letter-spacing:-.4px;line-height:40px;font-size:32px;font-weight:700;white-space:pre-wrap}.VPHero.has-image .name[data-v-303bb580],.VPHero.has-image .text[data-v-303bb580]{margin:0 auto}.name[data-v-303bb580]{color:var(--vp-home-hero-name-color)}.clip[data-v-303bb580]{background:var(--vp-home-hero-name-background);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:var(--vp-home-hero-name-color)}@media (min-width: 640px){.name[data-v-303bb580],.text[data-v-303bb580]{max-width:576px;line-height:56px;font-size:48px}}@media (min-width: 960px){.name[data-v-303bb580],.text[data-v-303bb580]{line-height:64px;font-size:56px}.VPHero.has-image .name[data-v-303bb580],.VPHero.has-image .text[data-v-303bb580]{margin:0}}.tagline[data-v-303bb580]{padding-top:8px;max-width:392px;line-height:28px;font-size:18px;font-weight:500;white-space:pre-wrap;color:var(--vp-c-text-2)}.VPHero.has-image .tagline[data-v-303bb580]{margin:0 auto}@media (min-width: 640px){.tagline[data-v-303bb580]{padding-top:12px;max-width:576px;line-height:32px;font-size:20px}}@media (min-width: 960px){.tagline[data-v-303bb580]{line-height:36px;font-size:24px}.VPHero.has-image .tagline[data-v-303bb580]{margin:0}}.actions[data-v-303bb580]{display:flex;flex-wrap:wrap;margin:-6px;padding-top:24px}.VPHero.has-image .actions[data-v-303bb580]{justify-content:center}@media (min-width: 640px){.actions[data-v-303bb580]{padding-top:32px}}@media (min-width: 960px){.VPHero.has-image .actions[data-v-303bb580]{justify-content:flex-start}}.action[data-v-303bb580]{flex-shrink:0;padding:6px}.image[data-v-303bb580]{order:1;margin:-76px -24px -48px}@media (min-width: 640px){.image[data-v-303bb580]{margin:-108px -24px -48px}}@media (min-width: 960px){.image[data-v-303bb580]{flex-grow:1;order:2;margin:0;min-height:100%}}.image-container[data-v-303bb580]{position:relative;margin:0 auto;width:320px;height:320px}@media (min-width: 640px){.image-container[data-v-303bb580]{width:392px;height:392px}}@media (min-width: 960px){.image-container[data-v-303bb580]{display:flex;justify-content:center;align-items:center;width:100%;height:100%;transform:translate(-32px,-32px)}}.image-bg[data-v-303bb580]{position:absolute;top:50%;left:50%;border-radius:50%;width:192px;height:192px;background-image:var(--vp-home-hero-image-background-image);filter:var(--vp-home-hero-image-filter);transform:translate(-50%,-50%)}@media (min-width: 640px){.image-bg[data-v-303bb580]{width:256px;height:256px}}@media (min-width: 960px){.image-bg[data-v-303bb580]{width:320px;height:320px}}[data-v-303bb580] .image-src{position:absolute;top:50%;left:50%;max-width:192px;max-height:192px;transform:translate(-50%,-50%)}@media (min-width: 640px){[data-v-303bb580] .image-src{max-width:256px;max-height:256px}}@media (min-width: 960px){[data-v-303bb580] .image-src{max-width:320px;max-height:320px}}.VPFeature[data-v-a3976bdc]{display:block;border:1px solid var(--vp-c-bg-soft);border-radius:12px;height:100%;background-color:var(--vp-c-bg-soft);transition:border-color .25s,background-color .25s}.VPFeature.link[data-v-a3976bdc]:hover{border-color:var(--vp-c-brand-1)}.box[data-v-a3976bdc]{display:flex;flex-direction:column;padding:24px;height:100%}.box[data-v-a3976bdc]>.VPImage{margin-bottom:20px}.icon[data-v-a3976bdc]{display:flex;justify-content:center;align-items:center;margin-bottom:20px;border-radius:6px;background-color:var(--vp-c-default-soft);width:48px;height:48px;font-size:24px;transition:background-color .25s}.title[data-v-a3976bdc]{line-height:24px;font-size:16px;font-weight:600}.details[data-v-a3976bdc]{flex-grow:1;padding-top:8px;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.link-text[data-v-a3976bdc]{padding-top:8px}.link-text-value[data-v-a3976bdc]{display:flex;align-items:center;font-size:14px;font-weight:500;color:var(--vp-c-brand-1)}.link-text-icon[data-v-a3976bdc]{margin-left:6px}.VPFeatures[data-v-a6181336]{position:relative;padding:0 24px}@media (min-width: 640px){.VPFeatures[data-v-a6181336]{padding:0 48px}}@media (min-width: 960px){.VPFeatures[data-v-a6181336]{padding:0 64px}}.container[data-v-a6181336]{margin:0 auto;max-width:1152px}.items[data-v-a6181336]{display:flex;flex-wrap:wrap;margin:-8px}.item[data-v-a6181336]{padding:8px;width:100%}@media (min-width: 640px){.item.grid-2[data-v-a6181336],.item.grid-4[data-v-a6181336],.item.grid-6[data-v-a6181336]{width:50%}}@media (min-width: 768px){.item.grid-2[data-v-a6181336],.item.grid-4[data-v-a6181336]{width:50%}.item.grid-3[data-v-a6181336],.item.grid-6[data-v-a6181336]{width:calc(100% / 3)}}@media (min-width: 960px){.item.grid-4[data-v-a6181336]{width:25%}}.container[data-v-8e2d4988]{margin:auto;width:100%;max-width:1280px;padding:0 24px}@media (min-width: 640px){.container[data-v-8e2d4988]{padding:0 48px}}@media (min-width: 960px){.container[data-v-8e2d4988]{width:100%;padding:0 64px}}.vp-doc[data-v-8e2d4988] .VPHomeSponsors,.vp-doc[data-v-8e2d4988] .VPTeamPage{margin-left:var(--vp-offset, calc(50% - 50vw) );margin-right:var(--vp-offset, calc(50% - 50vw) )}.vp-doc[data-v-8e2d4988] .VPHomeSponsors h2{border-top:none;letter-spacing:normal}.vp-doc[data-v-8e2d4988] .VPHomeSponsors a,.vp-doc[data-v-8e2d4988] .VPTeamPage a{text-decoration:none}.VPHome[data-v-686f80a6]{margin-bottom:96px}@media (min-width: 768px){.VPHome[data-v-686f80a6]{margin-bottom:128px}}.VPContent[data-v-1428d186]{flex-grow:1;flex-shrink:0;margin:var(--vp-layout-top-height, 0px) auto 0;width:100%}.VPContent.is-home[data-v-1428d186]{width:100%;max-width:100%}.VPContent.has-sidebar[data-v-1428d186]{margin:0}@media (min-width: 960px){.VPContent[data-v-1428d186]{padding-top:var(--vp-nav-height)}.VPContent.has-sidebar[data-v-1428d186]{margin:var(--vp-layout-top-height, 0px) 0 0;padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPContent.has-sidebar[data-v-1428d186]{padding-right:calc((100vw - var(--vp-layout-max-width)) / 2);padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.VPFooter[data-v-e315a0ad]{position:relative;z-index:var(--vp-z-index-footer);border-top:1px solid var(--vp-c-gutter);padding:32px 24px;background-color:var(--vp-c-bg)}.VPFooter.has-sidebar[data-v-e315a0ad]{display:none}.VPFooter[data-v-e315a0ad] a{text-decoration-line:underline;text-underline-offset:2px;transition:color .25s}.VPFooter[data-v-e315a0ad] a:hover{color:var(--vp-c-text-1)}@media (min-width: 768px){.VPFooter[data-v-e315a0ad]{padding:32px}}.container[data-v-e315a0ad]{margin:0 auto;max-width:var(--vp-layout-max-width);text-align:center}.message[data-v-e315a0ad],.copyright[data-v-e315a0ad]{line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.VPLocalNavOutlineDropdown[data-v-17a5e62e]{padding:12px 20px 11px}@media (min-width: 960px){.VPLocalNavOutlineDropdown[data-v-17a5e62e]{padding:12px 36px 11px}}.VPLocalNavOutlineDropdown button[data-v-17a5e62e]{display:block;font-size:12px;font-weight:500;line-height:24px;color:var(--vp-c-text-2);transition:color .5s;position:relative}.VPLocalNavOutlineDropdown button[data-v-17a5e62e]:hover{color:var(--vp-c-text-1);transition:color .25s}.VPLocalNavOutlineDropdown button.open[data-v-17a5e62e]{color:var(--vp-c-text-1)}.icon[data-v-17a5e62e]{display:inline-block;vertical-align:middle;margin-left:2px;font-size:14px;transform:rotate(0);transition:transform .25s}@media (min-width: 960px){.VPLocalNavOutlineDropdown button[data-v-17a5e62e]{font-size:14px}.icon[data-v-17a5e62e]{font-size:16px}}.open>.icon[data-v-17a5e62e]{transform:rotate(90deg)}.items[data-v-17a5e62e]{position:absolute;top:40px;right:16px;left:16px;display:grid;gap:1px;border:1px solid var(--vp-c-border);border-radius:8px;background-color:var(--vp-c-gutter);max-height:calc(var(--vp-vh, 100vh) - 86px);overflow:hidden auto;box-shadow:var(--vp-shadow-3)}@media (min-width: 960px){.items[data-v-17a5e62e]{right:auto;left:calc(var(--vp-sidebar-width) + 32px);width:320px}}.header[data-v-17a5e62e]{background-color:var(--vp-c-bg-soft)}.top-link[data-v-17a5e62e]{display:block;padding:0 16px;line-height:48px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1)}.outline[data-v-17a5e62e]{padding:8px 0;background-color:var(--vp-c-bg-soft)}.flyout-enter-active[data-v-17a5e62e]{transition:all .2s ease-out}.flyout-leave-active[data-v-17a5e62e]{transition:all .15s ease-in}.flyout-enter-from[data-v-17a5e62e],.flyout-leave-to[data-v-17a5e62e]{opacity:0;transform:translateY(-16px)}.VPLocalNav[data-v-a6f0e41e]{position:sticky;top:0;left:0;z-index:var(--vp-z-index-local-nav);border-bottom:1px solid var(--vp-c-gutter);padding-top:var(--vp-layout-top-height, 0px);width:100%;background-color:var(--vp-local-nav-bg-color)}.VPLocalNav.fixed[data-v-a6f0e41e]{position:fixed}@media (min-width: 960px){.VPLocalNav[data-v-a6f0e41e]{top:var(--vp-nav-height)}.VPLocalNav.has-sidebar[data-v-a6f0e41e]{padding-left:var(--vp-sidebar-width)}.VPLocalNav.empty[data-v-a6f0e41e]{display:none}}@media (min-width: 1280px){.VPLocalNav[data-v-a6f0e41e]{display:none}}@media (min-width: 1440px){.VPLocalNav.has-sidebar[data-v-a6f0e41e]{padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.container[data-v-a6f0e41e]{display:flex;justify-content:space-between;align-items:center}.menu[data-v-a6f0e41e]{display:flex;align-items:center;padding:12px 24px 11px;line-height:24px;font-size:12px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.menu[data-v-a6f0e41e]:hover{color:var(--vp-c-text-1);transition:color .25s}@media (min-width: 768px){.menu[data-v-a6f0e41e]{padding:0 32px}}@media (min-width: 960px){.menu[data-v-a6f0e41e]{display:none}}.menu-icon[data-v-a6f0e41e]{margin-right:8px;font-size:14px}.VPOutlineDropdown[data-v-a6f0e41e]{padding:12px 24px 11px}@media (min-width: 768px){.VPOutlineDropdown[data-v-a6f0e41e]{padding:12px 32px 11px}}.VPSwitch[data-v-1d5665e3]{position:relative;border-radius:11px;display:block;width:40px;height:22px;flex-shrink:0;border:1px solid var(--vp-input-border-color);background-color:var(--vp-input-switch-bg-color);transition:border-color .25s!important}.VPSwitch[data-v-1d5665e3]:hover{border-color:var(--vp-c-brand-1)}.check[data-v-1d5665e3]{position:absolute;top:1px;left:1px;width:18px;height:18px;border-radius:50%;background-color:var(--vp-c-neutral-inverse);box-shadow:var(--vp-shadow-1);transition:transform .25s!important}.icon[data-v-1d5665e3]{position:relative;display:block;width:18px;height:18px;border-radius:50%;overflow:hidden}.icon[data-v-1d5665e3] [class^=vpi-]{position:absolute;top:3px;left:3px;width:12px;height:12px;color:var(--vp-c-text-2)}.dark .icon[data-v-1d5665e3] [class^=vpi-]{color:var(--vp-c-text-1);transition:opacity .25s!important}.sun[data-v-d1f28634]{opacity:1}.moon[data-v-d1f28634],.dark .sun[data-v-d1f28634]{opacity:0}.dark .moon[data-v-d1f28634]{opacity:1}.dark .VPSwitchAppearance[data-v-d1f28634] .check{transform:translate(18px)}.VPNavBarAppearance[data-v-e6aabb21]{display:none}@media (min-width: 1280px){.VPNavBarAppearance[data-v-e6aabb21]{display:flex;align-items:center}}.VPMenuGroup+.VPMenuLink[data-v-43f1e123]{margin:12px -12px 0;border-top:1px solid var(--vp-c-divider);padding:12px 12px 0}.link[data-v-43f1e123]{display:block;border-radius:6px;padding:0 12px;line-height:32px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);white-space:nowrap;transition:background-color .25s,color .25s}.link[data-v-43f1e123]:hover{color:var(--vp-c-brand-1);background-color:var(--vp-c-default-soft)}.link.active[data-v-43f1e123]{color:var(--vp-c-brand-1)}.VPMenuGroup[data-v-69e747b5]{margin:12px -12px 0;border-top:1px solid var(--vp-c-divider);padding:12px 12px 0}.VPMenuGroup[data-v-69e747b5]:first-child{margin-top:0;border-top:0;padding-top:0}.VPMenuGroup+.VPMenuGroup[data-v-69e747b5]{margin-top:12px;border-top:1px solid var(--vp-c-divider)}.title[data-v-69e747b5]{padding:0 12px;line-height:32px;font-size:14px;font-weight:600;color:var(--vp-c-text-2);white-space:nowrap;transition:color .25s}.VPMenu[data-v-e7ea1737]{border-radius:12px;padding:12px;min-width:128px;border:1px solid var(--vp-c-divider);background-color:var(--vp-c-bg-elv);box-shadow:var(--vp-shadow-3);transition:background-color .5s;max-height:calc(100vh - var(--vp-nav-height));overflow-y:auto}.VPMenu[data-v-e7ea1737] .group{margin:0 -12px;padding:0 12px 12px}.VPMenu[data-v-e7ea1737] .group+.group{border-top:1px solid var(--vp-c-divider);padding:11px 12px 12px}.VPMenu[data-v-e7ea1737] .group:last-child{padding-bottom:0}.VPMenu[data-v-e7ea1737] .group+.item{border-top:1px solid var(--vp-c-divider);padding:11px 16px 0}.VPMenu[data-v-e7ea1737] .item{padding:0 16px;white-space:nowrap}.VPMenu[data-v-e7ea1737] .label{flex-grow:1;line-height:28px;font-size:12px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.VPMenu[data-v-e7ea1737] .action{padding-left:24px}.VPFlyout[data-v-b6c34ac9]{position:relative}.VPFlyout[data-v-b6c34ac9]:hover{color:var(--vp-c-brand-1);transition:color .25s}.VPFlyout:hover .text[data-v-b6c34ac9]{color:var(--vp-c-text-2)}.VPFlyout:hover .icon[data-v-b6c34ac9]{fill:var(--vp-c-text-2)}.VPFlyout.active .text[data-v-b6c34ac9]{color:var(--vp-c-brand-1)}.VPFlyout.active:hover .text[data-v-b6c34ac9]{color:var(--vp-c-brand-2)}.VPFlyout:hover .menu[data-v-b6c34ac9],.button[aria-expanded=true]+.menu[data-v-b6c34ac9]{opacity:1;visibility:visible;transform:translateY(0)}.button[aria-expanded=false]+.menu[data-v-b6c34ac9]{opacity:0;visibility:hidden;transform:translateY(0)}.button[data-v-b6c34ac9]{display:flex;align-items:center;padding:0 12px;height:var(--vp-nav-height);color:var(--vp-c-text-1);transition:color .5s}.text[data-v-b6c34ac9]{display:flex;align-items:center;line-height:var(--vp-nav-height);font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.option-icon[data-v-b6c34ac9]{margin-right:0;font-size:16px}.text-icon[data-v-b6c34ac9]{margin-left:4px;font-size:14px}.icon[data-v-b6c34ac9]{font-size:20px;transition:fill .25s}.menu[data-v-b6c34ac9]{position:absolute;top:calc(var(--vp-nav-height) / 2 + 20px);right:0;opacity:0;visibility:hidden;transition:opacity .25s,visibility .25s,transform .25s}.VPSocialLink[data-v-eee4e7cb]{display:flex;justify-content:center;align-items:center;width:36px;height:36px;color:var(--vp-c-text-2);transition:color .5s}.VPSocialLink[data-v-eee4e7cb]:hover{color:var(--vp-c-text-1);transition:color .25s}.VPSocialLink[data-v-eee4e7cb]>svg,.VPSocialLink[data-v-eee4e7cb]>[class^=vpi-social-]{width:20px;height:20px;fill:currentColor}.VPSocialLinks[data-v-7bc22406]{display:flex;justify-content:center}.VPNavBarExtra[data-v-d0bd9dde]{display:none;margin-right:-12px}@media (min-width: 768px){.VPNavBarExtra[data-v-d0bd9dde]{display:block}}@media (min-width: 1280px){.VPNavBarExtra[data-v-d0bd9dde]{display:none}}.trans-title[data-v-d0bd9dde]{padding:0 24px 0 12px;line-height:32px;font-size:14px;font-weight:700;color:var(--vp-c-text-1)}.item.appearance[data-v-d0bd9dde],.item.social-links[data-v-d0bd9dde]{display:flex;align-items:center;padding:0 12px}.item.appearance[data-v-d0bd9dde]{min-width:176px}.appearance-action[data-v-d0bd9dde]{margin-right:-2px}.social-links-list[data-v-d0bd9dde]{margin:-4px -8px}.VPNavBarHamburger[data-v-e5dd9c1c]{display:flex;justify-content:center;align-items:center;width:48px;height:var(--vp-nav-height)}@media (min-width: 768px){.VPNavBarHamburger[data-v-e5dd9c1c]{display:none}}.container[data-v-e5dd9c1c]{position:relative;width:16px;height:14px;overflow:hidden}.VPNavBarHamburger:hover .top[data-v-e5dd9c1c]{top:0;left:0;transform:translate(4px)}.VPNavBarHamburger:hover .middle[data-v-e5dd9c1c]{top:6px;left:0;transform:translate(0)}.VPNavBarHamburger:hover .bottom[data-v-e5dd9c1c]{top:12px;left:0;transform:translate(8px)}.VPNavBarHamburger.active .top[data-v-e5dd9c1c]{top:6px;transform:translate(0) rotate(225deg)}.VPNavBarHamburger.active .middle[data-v-e5dd9c1c]{top:6px;transform:translate(16px)}.VPNavBarHamburger.active .bottom[data-v-e5dd9c1c]{top:6px;transform:translate(0) rotate(135deg)}.VPNavBarHamburger.active:hover .top[data-v-e5dd9c1c],.VPNavBarHamburger.active:hover .middle[data-v-e5dd9c1c],.VPNavBarHamburger.active:hover .bottom[data-v-e5dd9c1c]{background-color:var(--vp-c-text-2);transition:top .25s,background-color .25s,transform .25s}.top[data-v-e5dd9c1c],.middle[data-v-e5dd9c1c],.bottom[data-v-e5dd9c1c]{position:absolute;width:16px;height:2px;background-color:var(--vp-c-text-1);transition:top .25s,background-color .5s,transform .25s}.top[data-v-e5dd9c1c]{top:0;left:0;transform:translate(0)}.middle[data-v-e5dd9c1c]{top:6px;left:0;transform:translate(8px)}.bottom[data-v-e5dd9c1c]{top:12px;left:0;transform:translate(4px)}.VPNavBarMenuLink[data-v-9c663999]{display:flex;align-items:center;padding:0 12px;line-height:var(--vp-nav-height);font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.VPNavBarMenuLink.active[data-v-9c663999],.VPNavBarMenuLink[data-v-9c663999]:hover{color:var(--vp-c-brand-1)}.VPNavBarMenu[data-v-7f418b0f]{display:none}@media (min-width: 768px){.VPNavBarMenu[data-v-7f418b0f]{display:flex}}/*! @docsearch/css 3.6.0 | MIT License | © Algolia, Inc. and contributors | https://docsearch.algolia.com */:root{--docsearch-primary-color:#5468ff;--docsearch-text-color:#1c1e21;--docsearch-spacing:12px;--docsearch-icon-stroke-width:1.4;--docsearch-highlight-color:var(--docsearch-primary-color);--docsearch-muted-color:#969faf;--docsearch-container-background:rgba(101,108,133,.8);--docsearch-logo-color:#5468ff;--docsearch-modal-width:560px;--docsearch-modal-height:600px;--docsearch-modal-background:#f5f6f7;--docsearch-modal-shadow:inset 1px 1px 0 0 hsla(0,0%,100%,.5),0 3px 8px 0 #555a64;--docsearch-searchbox-height:56px;--docsearch-searchbox-background:#ebedf0;--docsearch-searchbox-focus-background:#fff;--docsearch-searchbox-shadow:inset 0 0 0 2px var(--docsearch-primary-color);--docsearch-hit-height:56px;--docsearch-hit-color:#444950;--docsearch-hit-active-color:#fff;--docsearch-hit-background:#fff;--docsearch-hit-shadow:0 1px 3px 0 #d4d9e1;--docsearch-key-gradient:linear-gradient(-225deg,#d5dbe4,#f8f8f8);--docsearch-key-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 2px 1px rgba(30,35,90,.4);--docsearch-key-pressed-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 1px 0 rgba(30,35,90,.4);--docsearch-footer-height:44px;--docsearch-footer-background:#fff;--docsearch-footer-shadow:0 -1px 0 0 #e0e3e8,0 -3px 6px 0 rgba(69,98,155,.12)}html[data-theme=dark]{--docsearch-text-color:#f5f6f7;--docsearch-container-background:rgba(9,10,17,.8);--docsearch-modal-background:#15172a;--docsearch-modal-shadow:inset 1px 1px 0 0 #2c2e40,0 3px 8px 0 #000309;--docsearch-searchbox-background:#090a11;--docsearch-searchbox-focus-background:#000;--docsearch-hit-color:#bec3c9;--docsearch-hit-shadow:none;--docsearch-hit-background:#090a11;--docsearch-key-gradient:linear-gradient(-26.5deg,#565872,#31355b);--docsearch-key-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 2px 2px 0 rgba(3,4,9,.3);--docsearch-key-pressed-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 1px 1px 0 rgba(3,4,9,.30196078431372547);--docsearch-footer-background:#1e2136;--docsearch-footer-shadow:inset 0 1px 0 0 rgba(73,76,106,.5),0 -4px 8px 0 rgba(0,0,0,.2);--docsearch-logo-color:#fff;--docsearch-muted-color:#7f8497}.DocSearch-Button{align-items:center;background:var(--docsearch-searchbox-background);border:0;border-radius:40px;color:var(--docsearch-muted-color);cursor:pointer;display:flex;font-weight:500;height:36px;justify-content:space-between;margin:0 0 0 16px;padding:0 8px;-webkit-user-select:none;user-select:none}.DocSearch-Button:active,.DocSearch-Button:focus,.DocSearch-Button:hover{background:var(--docsearch-searchbox-focus-background);box-shadow:var(--docsearch-searchbox-shadow);color:var(--docsearch-text-color);outline:none}.DocSearch-Button-Container{align-items:center;display:flex}.DocSearch-Search-Icon{stroke-width:1.6}.DocSearch-Button .DocSearch-Search-Icon{color:var(--docsearch-text-color)}.DocSearch-Button-Placeholder{font-size:1rem;padding:0 12px 0 6px}.DocSearch-Button-Keys{display:flex;min-width:calc(40px + .8em)}.DocSearch-Button-Key{align-items:center;background:var(--docsearch-key-gradient);border-radius:3px;box-shadow:var(--docsearch-key-shadow);color:var(--docsearch-muted-color);display:flex;height:18px;justify-content:center;margin-right:.4em;position:relative;padding:0 0 2px;border:0;top:-1px;width:20px}.DocSearch-Button-Key--pressed{transform:translate3d(0,1px,0);box-shadow:var(--docsearch-key-pressed-shadow)}@media (max-width:768px){.DocSearch-Button-Keys,.DocSearch-Button-Placeholder{display:none}}.DocSearch--active{overflow:hidden!important}.DocSearch-Container,.DocSearch-Container *{box-sizing:border-box}.DocSearch-Container{background-color:var(--docsearch-container-background);height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:200}.DocSearch-Container a{text-decoration:none}.DocSearch-Link{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;font:inherit;margin:0;padding:0}.DocSearch-Modal{background:var(--docsearch-modal-background);border-radius:6px;box-shadow:var(--docsearch-modal-shadow);flex-direction:column;margin:60px auto auto;max-width:var(--docsearch-modal-width);position:relative}.DocSearch-SearchBar{display:flex;padding:var(--docsearch-spacing) var(--docsearch-spacing) 0}.DocSearch-Form{align-items:center;background:var(--docsearch-searchbox-focus-background);border-radius:4px;box-shadow:var(--docsearch-searchbox-shadow);display:flex;height:var(--docsearch-searchbox-height);margin:0;padding:0 var(--docsearch-spacing);position:relative;width:100%}.DocSearch-Input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border:0;color:var(--docsearch-text-color);flex:1;font:inherit;font-size:1.2em;height:100%;outline:none;padding:0 0 0 8px;width:80%}.DocSearch-Input::placeholder{color:var(--docsearch-muted-color);opacity:1}.DocSearch-Input::-webkit-search-cancel-button,.DocSearch-Input::-webkit-search-decoration,.DocSearch-Input::-webkit-search-results-button,.DocSearch-Input::-webkit-search-results-decoration{display:none}.DocSearch-LoadingIndicator,.DocSearch-MagnifierLabel,.DocSearch-Reset{margin:0;padding:0}.DocSearch-MagnifierLabel,.DocSearch-Reset{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}.DocSearch-Container--Stalled .DocSearch-MagnifierLabel,.DocSearch-LoadingIndicator{display:none}.DocSearch-Container--Stalled .DocSearch-LoadingIndicator{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Reset{animation:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;right:0;stroke-width:var(--docsearch-icon-stroke-width)}}.DocSearch-Reset{animation:fade-in .1s ease-in forwards;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;padding:2px;right:0;stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Reset[hidden]{display:none}.DocSearch-Reset:hover{color:var(--docsearch-highlight-color)}.DocSearch-LoadingIndicator svg,.DocSearch-MagnifierLabel svg{height:24px;width:24px}.DocSearch-Cancel{display:none}.DocSearch-Dropdown{max-height:calc(var(--docsearch-modal-height) - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height));min-height:var(--docsearch-spacing);overflow-y:auto;overflow-y:overlay;padding:0 var(--docsearch-spacing);scrollbar-color:var(--docsearch-muted-color) var(--docsearch-modal-background);scrollbar-width:thin}.DocSearch-Dropdown::-webkit-scrollbar{width:12px}.DocSearch-Dropdown::-webkit-scrollbar-track{background:transparent}.DocSearch-Dropdown::-webkit-scrollbar-thumb{background-color:var(--docsearch-muted-color);border:3px solid var(--docsearch-modal-background);border-radius:20px}.DocSearch-Dropdown ul{list-style:none;margin:0;padding:0}.DocSearch-Label{font-size:.75em;line-height:1.6em}.DocSearch-Help,.DocSearch-Label{color:var(--docsearch-muted-color)}.DocSearch-Help{font-size:.9em;margin:0;-webkit-user-select:none;user-select:none}.DocSearch-Title{font-size:1.2em}.DocSearch-Logo a{display:flex}.DocSearch-Logo svg{color:var(--docsearch-logo-color);margin-left:8px}.DocSearch-Hits:last-of-type{margin-bottom:24px}.DocSearch-Hits mark{background:none;color:var(--docsearch-highlight-color)}.DocSearch-HitsFooter{color:var(--docsearch-muted-color);display:flex;font-size:.85em;justify-content:center;margin-bottom:var(--docsearch-spacing);padding:var(--docsearch-spacing)}.DocSearch-HitsFooter a{border-bottom:1px solid;color:inherit}.DocSearch-Hit{border-radius:4px;display:flex;padding-bottom:4px;position:relative}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--deleting{transition:none}}.DocSearch-Hit--deleting{opacity:0;transition:all .25s linear}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--favoriting{transition:none}}.DocSearch-Hit--favoriting{transform:scale(0);transform-origin:top center;transition:all .25s linear;transition-delay:.25s}.DocSearch-Hit a{background:var(--docsearch-hit-background);border-radius:4px;box-shadow:var(--docsearch-hit-shadow);display:block;padding-left:var(--docsearch-spacing);width:100%}.DocSearch-Hit-source{background:var(--docsearch-modal-background);color:var(--docsearch-highlight-color);font-size:.85em;font-weight:600;line-height:32px;margin:0 -4px;padding:8px 4px 0;position:sticky;top:0;z-index:10}.DocSearch-Hit-Tree{color:var(--docsearch-muted-color);height:var(--docsearch-hit-height);opacity:.5;stroke-width:var(--docsearch-icon-stroke-width);width:24px}.DocSearch-Hit[aria-selected=true] a{background-color:var(--docsearch-highlight-color)}.DocSearch-Hit[aria-selected=true] mark{text-decoration:underline}.DocSearch-Hit-Container{align-items:center;color:var(--docsearch-hit-color);display:flex;flex-direction:row;height:var(--docsearch-hit-height);padding:0 var(--docsearch-spacing) 0 0}.DocSearch-Hit-icon{height:20px;width:20px}.DocSearch-Hit-action,.DocSearch-Hit-icon{color:var(--docsearch-muted-color);stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Hit-action{align-items:center;display:flex;height:22px;width:22px}.DocSearch-Hit-action svg{display:block;height:18px;width:18px}.DocSearch-Hit-action+.DocSearch-Hit-action{margin-left:6px}.DocSearch-Hit-action-button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:inherit;cursor:pointer;padding:2px}svg.DocSearch-Hit-Select-Icon{display:none}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Select-Icon{display:block}.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:#0003;transition:background-color .1s ease-in}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{transition:none}}.DocSearch-Hit-action-button:focus path,.DocSearch-Hit-action-button:hover path{fill:#fff}.DocSearch-Hit-content-wrapper{display:flex;flex:1 1 auto;flex-direction:column;font-weight:500;justify-content:center;line-height:1.2em;margin:0 8px;overflow-x:hidden;position:relative;text-overflow:ellipsis;white-space:nowrap;width:80%}.DocSearch-Hit-title{font-size:.9em}.DocSearch-Hit-path{color:var(--docsearch-muted-color);font-size:.75em}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-action,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-icon,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-path,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-text,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-title,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Tree,.DocSearch-Hit[aria-selected=true] mark{color:var(--docsearch-hit-active-color)!important}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:#0003;transition:none}}.DocSearch-ErrorScreen,.DocSearch-NoResults,.DocSearch-StartScreen{font-size:.9em;margin:0 auto;padding:36px 0;text-align:center;width:80%}.DocSearch-Screen-Icon{color:var(--docsearch-muted-color);padding-bottom:12px}.DocSearch-NoResults-Prefill-List{display:inline-block;padding-bottom:24px;text-align:left}.DocSearch-NoResults-Prefill-List ul{display:inline-block;padding:8px 0 0}.DocSearch-NoResults-Prefill-List li{list-style-position:inside;list-style-type:"» "}.DocSearch-Prefill{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:1em;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;font-size:1em;font-weight:700;padding:0}.DocSearch-Prefill:focus,.DocSearch-Prefill:hover{outline:none;text-decoration:underline}.DocSearch-Footer{align-items:center;background:var(--docsearch-footer-background);border-radius:0 0 8px 8px;box-shadow:var(--docsearch-footer-shadow);display:flex;flex-direction:row-reverse;flex-shrink:0;height:var(--docsearch-footer-height);justify-content:space-between;padding:0 var(--docsearch-spacing);position:relative;-webkit-user-select:none;user-select:none;width:100%;z-index:300}.DocSearch-Commands{color:var(--docsearch-muted-color);display:flex;list-style:none;margin:0;padding:0}.DocSearch-Commands li{align-items:center;display:flex}.DocSearch-Commands li:not(:last-of-type){margin-right:.8em}.DocSearch-Commands-Key{align-items:center;background:var(--docsearch-key-gradient);border-radius:2px;box-shadow:var(--docsearch-key-shadow);display:flex;height:18px;justify-content:center;margin-right:.4em;padding:0 0 1px;color:var(--docsearch-muted-color);border:0;width:20px}.DocSearch-VisuallyHiddenForAccessibility{clip:rect(0 0 0 0);clip-path:inset(50%);height:1px;overflow:hidden;position:absolute;white-space:nowrap;width:1px}@media (max-width:768px){:root{--docsearch-spacing:10px;--docsearch-footer-height:40px}.DocSearch-Dropdown{height:100%}.DocSearch-Container{height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);position:absolute}.DocSearch-Footer{border-radius:0;bottom:0;position:absolute}.DocSearch-Hit-content-wrapper{display:flex;position:relative;width:80%}.DocSearch-Modal{border-radius:0;box-shadow:none;height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);margin:0;max-width:100%;width:100%}.DocSearch-Dropdown{max-height:calc(var(--docsearch-vh, 1vh)*100 - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height))}.DocSearch-Cancel{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;flex:none;font:inherit;font-size:1em;font-weight:500;margin-left:var(--docsearch-spacing);outline:none;overflow:hidden;padding:0;-webkit-user-select:none;user-select:none;white-space:nowrap}.DocSearch-Commands,.DocSearch-Hit-Tree{display:none}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}[class*=DocSearch]{--docsearch-primary-color: var(--vp-c-brand-1);--docsearch-highlight-color: var(--docsearch-primary-color);--docsearch-text-color: var(--vp-c-text-1);--docsearch-muted-color: var(--vp-c-text-2);--docsearch-searchbox-shadow: none;--docsearch-searchbox-background: transparent;--docsearch-searchbox-focus-background: transparent;--docsearch-key-gradient: transparent;--docsearch-key-shadow: none;--docsearch-modal-background: var(--vp-c-bg-soft);--docsearch-footer-background: var(--vp-c-bg)}.dark [class*=DocSearch]{--docsearch-modal-shadow: none;--docsearch-footer-shadow: none;--docsearch-logo-color: var(--vp-c-text-2);--docsearch-hit-background: var(--vp-c-default-soft);--docsearch-hit-color: var(--vp-c-text-2);--docsearch-hit-shadow: none}.DocSearch-Button{display:flex;justify-content:center;align-items:center;margin:0;padding:0;width:48px;height:55px;background:transparent;transition:border-color .25s}.DocSearch-Button:hover{background:transparent}.DocSearch-Button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}.DocSearch-Button-Key--pressed{transform:none;box-shadow:none}.DocSearch-Button:focus:not(:focus-visible){outline:none!important}@media (min-width: 768px){.DocSearch-Button{justify-content:flex-start;border:1px solid transparent;border-radius:8px;padding:0 10px 0 12px;width:100%;height:40px;background-color:var(--vp-c-bg-alt)}.DocSearch-Button:hover{border-color:var(--vp-c-brand-1);background:var(--vp-c-bg-alt)}}.DocSearch-Button .DocSearch-Button-Container{display:flex;align-items:center}.DocSearch-Button .DocSearch-Search-Icon{position:relative;width:16px;height:16px;color:var(--vp-c-text-1);fill:currentColor;transition:color .5s}.DocSearch-Button:hover .DocSearch-Search-Icon{color:var(--vp-c-text-1)}@media (min-width: 768px){.DocSearch-Button .DocSearch-Search-Icon{top:1px;margin-right:8px;width:14px;height:14px;color:var(--vp-c-text-2)}}.DocSearch-Button .DocSearch-Button-Placeholder{display:none;margin-top:2px;padding:0 16px 0 0;font-size:13px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.DocSearch-Button:hover .DocSearch-Button-Placeholder{color:var(--vp-c-text-1)}@media (min-width: 768px){.DocSearch-Button .DocSearch-Button-Placeholder{display:inline-block}}.DocSearch-Button .DocSearch-Button-Keys{direction:ltr;display:none;min-width:auto}@media (min-width: 768px){.DocSearch-Button .DocSearch-Button-Keys{display:flex;align-items:center}}.DocSearch-Button .DocSearch-Button-Key{display:block;margin:2px 0 0;border:1px solid var(--vp-c-divider);border-right:none;border-radius:4px 0 0 4px;padding-left:6px;min-width:0;width:auto;height:22px;line-height:22px;font-family:var(--vp-font-family-base);font-size:12px;font-weight:500;transition:color .5s,border-color .5s}.DocSearch-Button .DocSearch-Button-Key+.DocSearch-Button-Key{border-right:1px solid var(--vp-c-divider);border-left:none;border-radius:0 4px 4px 0;padding-left:2px;padding-right:6px}.DocSearch-Button .DocSearch-Button-Key:first-child{font-size:0!important}.DocSearch-Button .DocSearch-Button-Key:first-child:after{content:"Ctrl";font-size:12px;letter-spacing:normal;color:var(--docsearch-muted-color)}.mac .DocSearch-Button .DocSearch-Button-Key:first-child:after{content:"⌘"}.DocSearch-Button .DocSearch-Button-Key:first-child>*{display:none}.DocSearch-Search-Icon{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke-width='1.6' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' d='m14.386 14.386 4.088 4.088-4.088-4.088A7.533 7.533 0 1 1 3.733 3.733a7.533 7.533 0 0 1 10.653 10.653z'/%3E%3C/svg%3E")}.VPNavBarSearch{display:flex;align-items:center}@media (min-width: 768px){.VPNavBarSearch{flex-grow:1;padding-left:24px}}@media (min-width: 960px){.VPNavBarSearch{padding-left:32px}}.dark .DocSearch-Footer{border-top:1px solid var(--vp-c-divider)}.DocSearch-Form{border:1px solid var(--vp-c-brand-1);background-color:var(--vp-c-white)}.dark .DocSearch-Form{background-color:var(--vp-c-default-soft)}.DocSearch-Screen-Icon>svg{margin:auto}.VPNavBarSocialLinks[data-v-0394ad82]{display:none}@media (min-width: 1280px){.VPNavBarSocialLinks[data-v-0394ad82]{display:flex;align-items:center}}.title[data-v-ab179fa1]{display:flex;align-items:center;border-bottom:1px solid transparent;width:100%;height:var(--vp-nav-height);font-size:16px;font-weight:600;color:var(--vp-c-text-1);transition:opacity .25s}@media (min-width: 960px){.title[data-v-ab179fa1]{flex-shrink:0}.VPNavBarTitle.has-sidebar .title[data-v-ab179fa1]{border-bottom-color:var(--vp-c-divider)}}[data-v-ab179fa1] .logo{margin-right:8px;height:var(--vp-nav-logo-height)}.VPNavBarTranslations[data-v-88af2de4]{display:none}@media (min-width: 1280px){.VPNavBarTranslations[data-v-88af2de4]{display:flex;align-items:center}}.title[data-v-88af2de4]{padding:0 24px 0 12px;line-height:32px;font-size:14px;font-weight:700;color:var(--vp-c-text-1)}.VPNavBar[data-v-ccf7ddec]{position:relative;height:var(--vp-nav-height);pointer-events:none;white-space:nowrap;transition:background-color .5s}.VPNavBar[data-v-ccf7ddec]:not(.home){background-color:var(--vp-nav-bg-color)}@media (min-width: 960px){.VPNavBar[data-v-ccf7ddec]:not(.home){background-color:transparent}.VPNavBar[data-v-ccf7ddec]:not(.has-sidebar):not(.home.top){background-color:var(--vp-nav-bg-color)}}.wrapper[data-v-ccf7ddec]{padding:0 8px 0 24px}@media (min-width: 768px){.wrapper[data-v-ccf7ddec]{padding:0 32px}}@media (min-width: 960px){.VPNavBar.has-sidebar .wrapper[data-v-ccf7ddec]{padding:0}}.container[data-v-ccf7ddec]{display:flex;justify-content:space-between;margin:0 auto;max-width:calc(var(--vp-layout-max-width) - 64px);height:var(--vp-nav-height);pointer-events:none}.container>.title[data-v-ccf7ddec],.container>.content[data-v-ccf7ddec]{pointer-events:none}.container[data-v-ccf7ddec] *{pointer-events:auto}@media (min-width: 960px){.VPNavBar.has-sidebar .container[data-v-ccf7ddec]{max-width:100%}}.title[data-v-ccf7ddec]{flex-shrink:0;height:calc(var(--vp-nav-height) - 1px);transition:background-color .5s}@media (min-width: 960px){.VPNavBar.has-sidebar .title[data-v-ccf7ddec]{position:absolute;top:0;left:0;z-index:2;padding:0 32px;width:var(--vp-sidebar-width);height:var(--vp-nav-height);background-color:transparent}}@media (min-width: 1440px){.VPNavBar.has-sidebar .title[data-v-ccf7ddec]{padding-left:max(32px,calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));width:calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px)}}.content[data-v-ccf7ddec]{flex-grow:1}@media (min-width: 960px){.VPNavBar.has-sidebar .content[data-v-ccf7ddec]{position:relative;z-index:1;padding-right:32px;padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPNavBar.has-sidebar .content[data-v-ccf7ddec]{padding-right:calc((100vw - var(--vp-layout-max-width)) / 2 + 32px);padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.content-body[data-v-ccf7ddec]{display:flex;justify-content:flex-end;align-items:center;height:var(--vp-nav-height);transition:background-color .5s}@media (min-width: 960px){.VPNavBar:not(.home.top) .content-body[data-v-ccf7ddec]{position:relative;background-color:var(--vp-nav-bg-color)}.VPNavBar:not(.has-sidebar):not(.home.top) .content-body[data-v-ccf7ddec]{background-color:transparent}}@media (max-width: 767px){.content-body[data-v-ccf7ddec]{column-gap:.5rem}}.menu+.translations[data-v-ccf7ddec]:before,.menu+.appearance[data-v-ccf7ddec]:before,.menu+.social-links[data-v-ccf7ddec]:before,.translations+.appearance[data-v-ccf7ddec]:before,.appearance+.social-links[data-v-ccf7ddec]:before{margin-right:8px;margin-left:8px;width:1px;height:24px;background-color:var(--vp-c-divider);content:""}.menu+.appearance[data-v-ccf7ddec]:before,.translations+.appearance[data-v-ccf7ddec]:before{margin-right:16px}.appearance+.social-links[data-v-ccf7ddec]:before{margin-left:16px}.social-links[data-v-ccf7ddec]{margin-right:-8px}.divider[data-v-ccf7ddec]{width:100%;height:1px}@media (min-width: 960px){.VPNavBar.has-sidebar .divider[data-v-ccf7ddec]{padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPNavBar.has-sidebar .divider[data-v-ccf7ddec]{padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.divider-line[data-v-ccf7ddec]{width:100%;height:1px;transition:background-color .5s}.VPNavBar:not(.home) .divider-line[data-v-ccf7ddec]{background-color:var(--vp-c-gutter)}@media (min-width: 960px){.VPNavBar:not(.home.top) .divider-line[data-v-ccf7ddec]{background-color:var(--vp-c-gutter)}.VPNavBar:not(.has-sidebar):not(.home.top) .divider[data-v-ccf7ddec]{background-color:var(--vp-c-gutter)}}.VPNavScreenAppearance[data-v-2d7af913]{display:flex;justify-content:space-between;align-items:center;border-radius:8px;padding:12px 14px 12px 16px;background-color:var(--vp-c-bg-soft)}.text[data-v-2d7af913]{line-height:24px;font-size:12px;font-weight:500;color:var(--vp-c-text-2)}.VPNavScreenMenuLink[data-v-7f31e1f6]{display:block;border-bottom:1px solid var(--vp-c-divider);padding:12px 0 11px;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:border-color .25s,color .25s}.VPNavScreenMenuLink[data-v-7f31e1f6]:hover{color:var(--vp-c-brand-1)}.VPNavScreenMenuGroupLink[data-v-19976ae1]{display:block;margin-left:12px;line-height:32px;font-size:14px;font-weight:400;color:var(--vp-c-text-1);transition:color .25s}.VPNavScreenMenuGroupLink[data-v-19976ae1]:hover{color:var(--vp-c-brand-1)}.VPNavScreenMenuGroupSection[data-v-8133b170]{display:block}.title[data-v-8133b170]{line-height:32px;font-size:13px;font-weight:700;color:var(--vp-c-text-2);transition:color .25s}.VPNavScreenMenuGroup[data-v-ff6087d4]{border-bottom:1px solid var(--vp-c-divider);height:48px;overflow:hidden;transition:border-color .5s}.VPNavScreenMenuGroup .items[data-v-ff6087d4]{visibility:hidden}.VPNavScreenMenuGroup.open .items[data-v-ff6087d4]{visibility:visible}.VPNavScreenMenuGroup.open[data-v-ff6087d4]{padding-bottom:10px;height:auto}.VPNavScreenMenuGroup.open .button[data-v-ff6087d4]{padding-bottom:6px;color:var(--vp-c-brand-1)}.VPNavScreenMenuGroup.open .button-icon[data-v-ff6087d4]{transform:rotate(45deg)}.button[data-v-ff6087d4]{display:flex;justify-content:space-between;align-items:center;padding:12px 4px 11px 0;width:100%;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.button[data-v-ff6087d4]:hover{color:var(--vp-c-brand-1)}.button-icon[data-v-ff6087d4]{transition:transform .25s}.group[data-v-ff6087d4]:first-child{padding-top:0}.group+.group[data-v-ff6087d4],.group+.item[data-v-ff6087d4]{padding-top:4px}.VPNavScreenTranslations[data-v-858fe1a4]{height:24px;overflow:hidden}.VPNavScreenTranslations.open[data-v-858fe1a4]{height:auto}.title[data-v-858fe1a4]{display:flex;align-items:center;font-size:14px;font-weight:500;color:var(--vp-c-text-1)}.icon[data-v-858fe1a4]{font-size:16px}.icon.lang[data-v-858fe1a4]{margin-right:8px}.icon.chevron[data-v-858fe1a4]{margin-left:4px}.list[data-v-858fe1a4]{padding:4px 0 0 24px}.link[data-v-858fe1a4]{line-height:32px;font-size:13px;color:var(--vp-c-text-1)}.VPNavScreen[data-v-cc5739dd]{position:fixed;top:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 1px);right:0;bottom:0;left:0;padding:0 32px;width:100%;background-color:var(--vp-nav-screen-bg-color);overflow-y:auto;transition:background-color .5s;pointer-events:auto}.VPNavScreen.fade-enter-active[data-v-cc5739dd],.VPNavScreen.fade-leave-active[data-v-cc5739dd]{transition:opacity .25s}.VPNavScreen.fade-enter-active .container[data-v-cc5739dd],.VPNavScreen.fade-leave-active .container[data-v-cc5739dd]{transition:transform .25s ease}.VPNavScreen.fade-enter-from[data-v-cc5739dd],.VPNavScreen.fade-leave-to[data-v-cc5739dd]{opacity:0}.VPNavScreen.fade-enter-from .container[data-v-cc5739dd],.VPNavScreen.fade-leave-to .container[data-v-cc5739dd]{transform:translateY(-8px)}@media (min-width: 768px){.VPNavScreen[data-v-cc5739dd]{display:none}}.container[data-v-cc5739dd]{margin:0 auto;padding:24px 0 96px;max-width:288px}.menu+.translations[data-v-cc5739dd],.menu+.appearance[data-v-cc5739dd],.translations+.appearance[data-v-cc5739dd]{margin-top:24px}.menu+.social-links[data-v-cc5739dd]{margin-top:16px}.appearance+.social-links[data-v-cc5739dd]{margin-top:16px}.VPNav[data-v-ae24b3ad]{position:relative;top:var(--vp-layout-top-height, 0px);left:0;z-index:var(--vp-z-index-nav);width:100%;pointer-events:none;transition:background-color .5s}@media (min-width: 960px){.VPNav[data-v-ae24b3ad]{position:fixed}}.VPSidebarItem.level-0[data-v-b8d55f3b]{padding-bottom:24px}.VPSidebarItem.collapsed.level-0[data-v-b8d55f3b]{padding-bottom:10px}.item[data-v-b8d55f3b]{position:relative;display:flex;width:100%}.VPSidebarItem.collapsible>.item[data-v-b8d55f3b]{cursor:pointer}.indicator[data-v-b8d55f3b]{position:absolute;top:6px;bottom:6px;left:-17px;width:2px;border-radius:2px;transition:background-color .25s}.VPSidebarItem.level-2.is-active>.item>.indicator[data-v-b8d55f3b],.VPSidebarItem.level-3.is-active>.item>.indicator[data-v-b8d55f3b],.VPSidebarItem.level-4.is-active>.item>.indicator[data-v-b8d55f3b],.VPSidebarItem.level-5.is-active>.item>.indicator[data-v-b8d55f3b]{background-color:var(--vp-c-brand-1)}.link[data-v-b8d55f3b]{display:flex;align-items:center;flex-grow:1}.text[data-v-b8d55f3b]{flex-grow:1;padding:4px 0;line-height:24px;font-size:14px;transition:color .25s}.VPSidebarItem.level-0 .text[data-v-b8d55f3b]{font-weight:700;color:var(--vp-c-text-1)}.VPSidebarItem.level-1 .text[data-v-b8d55f3b],.VPSidebarItem.level-2 .text[data-v-b8d55f3b],.VPSidebarItem.level-3 .text[data-v-b8d55f3b],.VPSidebarItem.level-4 .text[data-v-b8d55f3b],.VPSidebarItem.level-5 .text[data-v-b8d55f3b]{font-weight:500;color:var(--vp-c-text-2)}.VPSidebarItem.level-0.is-link>.item>.link:hover .text[data-v-b8d55f3b],.VPSidebarItem.level-1.is-link>.item>.link:hover .text[data-v-b8d55f3b],.VPSidebarItem.level-2.is-link>.item>.link:hover .text[data-v-b8d55f3b],.VPSidebarItem.level-3.is-link>.item>.link:hover .text[data-v-b8d55f3b],.VPSidebarItem.level-4.is-link>.item>.link:hover .text[data-v-b8d55f3b],.VPSidebarItem.level-5.is-link>.item>.link:hover .text[data-v-b8d55f3b]{color:var(--vp-c-brand-1)}.VPSidebarItem.level-0.has-active>.item>.text[data-v-b8d55f3b],.VPSidebarItem.level-1.has-active>.item>.text[data-v-b8d55f3b],.VPSidebarItem.level-2.has-active>.item>.text[data-v-b8d55f3b],.VPSidebarItem.level-3.has-active>.item>.text[data-v-b8d55f3b],.VPSidebarItem.level-4.has-active>.item>.text[data-v-b8d55f3b],.VPSidebarItem.level-5.has-active>.item>.text[data-v-b8d55f3b],.VPSidebarItem.level-0.has-active>.item>.link>.text[data-v-b8d55f3b],.VPSidebarItem.level-1.has-active>.item>.link>.text[data-v-b8d55f3b],.VPSidebarItem.level-2.has-active>.item>.link>.text[data-v-b8d55f3b],.VPSidebarItem.level-3.has-active>.item>.link>.text[data-v-b8d55f3b],.VPSidebarItem.level-4.has-active>.item>.link>.text[data-v-b8d55f3b],.VPSidebarItem.level-5.has-active>.item>.link>.text[data-v-b8d55f3b]{color:var(--vp-c-text-1)}.VPSidebarItem.level-0.is-active>.item .link>.text[data-v-b8d55f3b],.VPSidebarItem.level-1.is-active>.item .link>.text[data-v-b8d55f3b],.VPSidebarItem.level-2.is-active>.item .link>.text[data-v-b8d55f3b],.VPSidebarItem.level-3.is-active>.item .link>.text[data-v-b8d55f3b],.VPSidebarItem.level-4.is-active>.item .link>.text[data-v-b8d55f3b],.VPSidebarItem.level-5.is-active>.item .link>.text[data-v-b8d55f3b]{color:var(--vp-c-brand-1)}.caret[data-v-b8d55f3b]{display:flex;justify-content:center;align-items:center;margin-right:-7px;width:32px;height:32px;color:var(--vp-c-text-3);cursor:pointer;transition:color .25s;flex-shrink:0}.item:hover .caret[data-v-b8d55f3b]{color:var(--vp-c-text-2)}.item:hover .caret[data-v-b8d55f3b]:hover{color:var(--vp-c-text-1)}.caret-icon[data-v-b8d55f3b]{font-size:18px;transform:rotate(90deg);transition:transform .25s}.VPSidebarItem.collapsed .caret-icon[data-v-b8d55f3b]{transform:rotate(0)}.VPSidebarItem.level-1 .items[data-v-b8d55f3b],.VPSidebarItem.level-2 .items[data-v-b8d55f3b],.VPSidebarItem.level-3 .items[data-v-b8d55f3b],.VPSidebarItem.level-4 .items[data-v-b8d55f3b],.VPSidebarItem.level-5 .items[data-v-b8d55f3b]{border-left:1px solid var(--vp-c-divider);padding-left:16px}.VPSidebarItem.collapsed .items[data-v-b8d55f3b]{display:none}.VPSidebar[data-v-575e6a36]{position:fixed;top:var(--vp-layout-top-height, 0px);bottom:0;left:0;z-index:var(--vp-z-index-sidebar);padding:32px 32px 96px;width:calc(100vw - 64px);max-width:320px;background-color:var(--vp-sidebar-bg-color);opacity:0;box-shadow:var(--vp-c-shadow-3);overflow-x:hidden;overflow-y:auto;transform:translate(-100%);transition:opacity .5s,transform .25s ease;overscroll-behavior:contain}.VPSidebar.open[data-v-575e6a36]{opacity:1;visibility:visible;transform:translate(0);transition:opacity .25s,transform .5s cubic-bezier(.19,1,.22,1)}.dark .VPSidebar[data-v-575e6a36]{box-shadow:var(--vp-shadow-1)}@media (min-width: 960px){.VPSidebar[data-v-575e6a36]{padding-top:var(--vp-nav-height);width:var(--vp-sidebar-width);max-width:100%;background-color:var(--vp-sidebar-bg-color);opacity:1;visibility:visible;box-shadow:none;transform:translate(0)}}@media (min-width: 1440px){.VPSidebar[data-v-575e6a36]{padding-left:max(32px,calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));width:calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px)}}@media (min-width: 960px){.curtain[data-v-575e6a36]{position:sticky;top:-64px;left:0;z-index:1;margin-top:calc(var(--vp-nav-height) * -1);margin-right:-32px;margin-left:-32px;height:var(--vp-nav-height);background-color:var(--vp-sidebar-bg-color)}}.nav[data-v-575e6a36]{outline:0}.group+.group[data-v-575e6a36]{border-top:1px solid var(--vp-c-divider);padding-top:10px}@media (min-width: 960px){.group[data-v-575e6a36]{padding-top:10px;width:calc(var(--vp-sidebar-width) - 64px)}}.VPSkipLink[data-v-0f60ec36]{top:8px;left:8px;padding:8px 16px;z-index:999;border-radius:8px;font-size:12px;font-weight:700;text-decoration:none;color:var(--vp-c-brand-1);box-shadow:var(--vp-shadow-3);background-color:var(--vp-c-bg)}.VPSkipLink[data-v-0f60ec36]:focus{height:auto;width:auto;clip:auto;clip-path:none}@media (min-width: 1280px){.VPSkipLink[data-v-0f60ec36]{top:14px;left:16px}}.Layout[data-v-5d98c3a5]{display:flex;flex-direction:column;min-height:100vh}.VPHomeSponsors[data-v-3d121b4a]{border-top:1px solid var(--vp-c-gutter);padding-top:88px!important}.VPHomeSponsors[data-v-3d121b4a]{margin:96px 0}@media (min-width: 768px){.VPHomeSponsors[data-v-3d121b4a]{margin:128px 0}}.VPHomeSponsors[data-v-3d121b4a]{padding:0 24px}@media (min-width: 768px){.VPHomeSponsors[data-v-3d121b4a]{padding:0 48px}}@media (min-width: 960px){.VPHomeSponsors[data-v-3d121b4a]{padding:0 64px}}.container[data-v-3d121b4a]{margin:0 auto;max-width:1152px}.love[data-v-3d121b4a]{margin:0 auto;width:fit-content;font-size:28px;color:var(--vp-c-text-3)}.icon[data-v-3d121b4a]{display:inline-block}.message[data-v-3d121b4a]{margin:0 auto;padding-top:10px;max-width:320px;text-align:center;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}.sponsors[data-v-3d121b4a]{padding-top:32px}.action[data-v-3d121b4a]{padding-top:40px;text-align:center}.VPTeamPage[data-v-7c57f839]{margin:96px 0}@media (min-width: 768px){.VPTeamPage[data-v-7c57f839]{margin:128px 0}}.VPHome .VPTeamPageTitle[data-v-7c57f839-s]{border-top:1px solid var(--vp-c-gutter);padding-top:88px!important}.VPTeamPageSection+.VPTeamPageSection[data-v-7c57f839-s],.VPTeamMembers+.VPTeamPageSection[data-v-7c57f839-s]{margin-top:64px}.VPTeamMembers+.VPTeamMembers[data-v-7c57f839-s]{margin-top:24px}@media (min-width: 768px){.VPTeamPageTitle+.VPTeamPageSection[data-v-7c57f839-s]{margin-top:16px}.VPTeamPageSection+.VPTeamPageSection[data-v-7c57f839-s],.VPTeamMembers+.VPTeamPageSection[data-v-7c57f839-s]{margin-top:96px}}.VPTeamMembers[data-v-7c57f839-s]{padding:0 24px}@media (min-width: 768px){.VPTeamMembers[data-v-7c57f839-s]{padding:0 48px}}@media (min-width: 960px){.VPTeamMembers[data-v-7c57f839-s]{padding:0 64px}}.VPTeamPageTitle[data-v-bf2cbdac]{padding:48px 32px;text-align:center}@media (min-width: 768px){.VPTeamPageTitle[data-v-bf2cbdac]{padding:64px 48px 48px}}@media (min-width: 960px){.VPTeamPageTitle[data-v-bf2cbdac]{padding:80px 64px 48px}}.title[data-v-bf2cbdac]{letter-spacing:0;line-height:44px;font-size:36px;font-weight:500}@media (min-width: 768px){.title[data-v-bf2cbdac]{letter-spacing:-.5px;line-height:56px;font-size:48px}}.lead[data-v-bf2cbdac]{margin:0 auto;max-width:512px;padding-top:12px;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}@media (min-width: 768px){.lead[data-v-bf2cbdac]{max-width:592px;letter-spacing:.15px;line-height:28px;font-size:20px}}.VPTeamPageSection[data-v-b1a88750]{padding:0 32px}@media (min-width: 768px){.VPTeamPageSection[data-v-b1a88750]{padding:0 48px}}@media (min-width: 960px){.VPTeamPageSection[data-v-b1a88750]{padding:0 64px}}.title[data-v-b1a88750]{position:relative;margin:0 auto;max-width:1152px;text-align:center;color:var(--vp-c-text-2)}.title-line[data-v-b1a88750]{position:absolute;top:16px;left:0;width:100%;height:1px;background-color:var(--vp-c-divider)}.title-text[data-v-b1a88750]{position:relative;display:inline-block;padding:0 24px;letter-spacing:0;line-height:32px;font-size:20px;font-weight:500;background-color:var(--vp-c-bg)}.lead[data-v-b1a88750]{margin:0 auto;max-width:480px;padding-top:12px;text-align:center;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}.members[data-v-b1a88750]{padding-top:40px}.VPTeamMembersItem[data-v-f3fa364a]{display:flex;flex-direction:column;gap:2px;border-radius:12px;width:100%;height:100%;overflow:hidden}.VPTeamMembersItem.small .profile[data-v-f3fa364a]{padding:32px}.VPTeamMembersItem.small .data[data-v-f3fa364a]{padding-top:20px}.VPTeamMembersItem.small .avatar[data-v-f3fa364a]{width:64px;height:64px}.VPTeamMembersItem.small .name[data-v-f3fa364a]{line-height:24px;font-size:16px}.VPTeamMembersItem.small .affiliation[data-v-f3fa364a]{padding-top:4px;line-height:20px;font-size:14px}.VPTeamMembersItem.small .desc[data-v-f3fa364a]{padding-top:12px;line-height:20px;font-size:14px}.VPTeamMembersItem.small .links[data-v-f3fa364a]{margin:0 -16px -20px;padding:10px 0 0}.VPTeamMembersItem.medium .profile[data-v-f3fa364a]{padding:48px 32px}.VPTeamMembersItem.medium .data[data-v-f3fa364a]{padding-top:24px;text-align:center}.VPTeamMembersItem.medium .avatar[data-v-f3fa364a]{width:96px;height:96px}.VPTeamMembersItem.medium .name[data-v-f3fa364a]{letter-spacing:.15px;line-height:28px;font-size:20px}.VPTeamMembersItem.medium .affiliation[data-v-f3fa364a]{padding-top:4px;font-size:16px}.VPTeamMembersItem.medium .desc[data-v-f3fa364a]{padding-top:16px;max-width:288px;font-size:16px}.VPTeamMembersItem.medium .links[data-v-f3fa364a]{margin:0 -16px -12px;padding:16px 12px 0}.profile[data-v-f3fa364a]{flex-grow:1;background-color:var(--vp-c-bg-soft)}.data[data-v-f3fa364a]{text-align:center}.avatar[data-v-f3fa364a]{position:relative;flex-shrink:0;margin:0 auto;border-radius:50%;box-shadow:var(--vp-shadow-3)}.avatar-img[data-v-f3fa364a]{position:absolute;top:0;right:0;bottom:0;left:0;border-radius:50%;object-fit:cover}.name[data-v-f3fa364a]{margin:0;font-weight:600}.affiliation[data-v-f3fa364a]{margin:0;font-weight:500;color:var(--vp-c-text-2)}.org.link[data-v-f3fa364a]{color:var(--vp-c-text-2);transition:color .25s}.org.link[data-v-f3fa364a]:hover{color:var(--vp-c-brand-1)}.desc[data-v-f3fa364a]{margin:0 auto}.desc[data-v-f3fa364a] a{font-weight:500;color:var(--vp-c-brand-1);text-decoration-style:dotted;transition:color .25s}.links[data-v-f3fa364a]{display:flex;justify-content:center;height:56px}.sp-link[data-v-f3fa364a]{display:flex;justify-content:center;align-items:center;text-align:center;padding:16px;font-size:14px;font-weight:500;color:var(--vp-c-sponsor);background-color:var(--vp-c-bg-soft);transition:color .25s,background-color .25s}.sp .sp-link.link[data-v-f3fa364a]:hover,.sp .sp-link.link[data-v-f3fa364a]:focus{outline:none;color:var(--vp-c-white);background-color:var(--vp-c-sponsor)}.sp-icon[data-v-f3fa364a]{margin-right:8px;font-size:16px}.VPTeamMembers.small .container[data-v-6cb0dbc4]{grid-template-columns:repeat(auto-fit,minmax(224px,1fr))}.VPTeamMembers.small.count-1 .container[data-v-6cb0dbc4]{max-width:276px}.VPTeamMembers.small.count-2 .container[data-v-6cb0dbc4]{max-width:576px}.VPTeamMembers.small.count-3 .container[data-v-6cb0dbc4]{max-width:876px}.VPTeamMembers.medium .container[data-v-6cb0dbc4]{grid-template-columns:repeat(auto-fit,minmax(256px,1fr))}@media (min-width: 375px){.VPTeamMembers.medium .container[data-v-6cb0dbc4]{grid-template-columns:repeat(auto-fit,minmax(288px,1fr))}}.VPTeamMembers.medium.count-1 .container[data-v-6cb0dbc4]{max-width:368px}.VPTeamMembers.medium.count-2 .container[data-v-6cb0dbc4]{max-width:760px}.container[data-v-6cb0dbc4]{display:grid;gap:24px;margin:0 auto;max-width:1152px}:root{--vp-nolebase-highlight-targeted-heading-color: var(--vp-custom-block-tip-text);--vp-nolebase-highlight-targeted-heading-bg: var(--vp-custom-block-tip-bg)}@keyframes vp-nolebase-highlight-targeted-heading-animation{0%{background-color:transparent;box-shadow:0 0 0 8px transparent}10%,35%{color:var(--vp-nolebase-highlight-targeted-heading-color);border-color:transparent;border-radius:4px;background-color:var(--vp-nolebase-highlight-targeted-heading-bg);box-shadow:0 0 0 8px var(--vp-nolebase-highlight-targeted-heading-bg)}99%{background-color:transparent;border-radius:4px;box-shadow:0 0 0 8px transparent}to{border-radius:0;background-color:transparent;box-shadow:none}}.VPNolebaseHighlightTargetedHeadingAnimated{animation:vp-nolebase-highlight-targeted-heading-animation 1.5s ease-in-out}*,:before,:after{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / .5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }::backdrop{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / .5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }@font-face{font-family:"Baloo 2";font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/baloo2/v21/wXK0E3kTposypRydzVT08TS3JnAmtdgazZpp_led7Q.woff2) format("woff2");unicode-range:U+0900-097F,U+1CD0-1CF9,U+200C-200D,U+20A8,U+20B9,U+20F0,U+25CC,U+A830-A839,U+A8E0-A8FF,U+11B00-11B09}@font-face{font-family:"Baloo 2";font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/baloo2/v21/wXK0E3kTposypRydzVT08TS3JnAmtdgazZpn_led7Q.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:"Baloo 2";font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/baloo2/v21/wXK0E3kTposypRydzVT08TS3JnAmtdgazZpm_led7Q.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:"Baloo 2";font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/baloo2/v21/wXK0E3kTposypRydzVT08TS3JnAmtdgazZpo_lc.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Chakra Petch;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/chakrapetch/v11/cIf6MapbsEk7TDLdtEz1BwkWi6pgeL4.woff2) format("woff2");unicode-range:U+0E01-0E5B,U+200C-200D,U+25CC}@font-face{font-family:Chakra Petch;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/chakrapetch/v11/cIf6MapbsEk7TDLdtEz1BwkWkKpgeL4.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Chakra Petch;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/chakrapetch/v11/cIf6MapbsEk7TDLdtEz1BwkWkapgeL4.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Chakra Petch;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/chakrapetch/v11/cIf6MapbsEk7TDLdtEz1BwkWn6pg.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Jura;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/jura/v31/z7NOdRfiaC4Vd8hhoPzfb5vBTP1d7ZurR_ibHw.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Jura;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/jura/v31/z7NOdRfiaC4Vd8hhoPzfb5vBTP1d7ZuiR_ibHw.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Jura;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/jura/v31/z7NOdRfiaC4Vd8hhoPzfb5vBTP1d7ZuqR_ibHw.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Jura;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/jura/v31/z7NOdRfiaC4Vd8hhoPzfb5vBTP1d7ZulR_ibHw.woff2) format("woff2");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:Jura;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/jura/v31/z7NOdRfiaC4Vd8hhoPzfb5vBTP1d7ZvuR_ibHw.woff2) format("woff2");unicode-range:U+200C-200D,U+2010,U+25CC,U+A900-A92F}@font-face{font-family:Jura;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/jura/v31/z7NOdRfiaC4Vd8hhoPzfb5vBTP1d7ZupR_ibHw.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Jura;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/jura/v31/z7NOdRfiaC4Vd8hhoPzfb5vBTP1d7ZuoR_ibHw.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Jura;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/jura/v31/z7NOdRfiaC4Vd8hhoPzfb5vBTP1d7ZumR_g.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Noto Sans;font-style:normal;font-weight:400;font-stretch:normal;font-display:swap;src:url(https://fonts.gstatic.com/s/notosans/v36/o-0mIpQlx3QUlC5A4PNB6Ryti20_6n1iPHjcz6L1SoM-jCpoiyD9A-9X6VLKzA.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Noto Sans;font-style:normal;font-weight:400;font-stretch:normal;font-display:swap;src:url(https://fonts.gstatic.com/s/notosans/v36/o-0mIpQlx3QUlC5A4PNB6Ryti20_6n1iPHjcz6L1SoM-jCpoiyD9A-9e6VLKzA.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Noto Sans;font-style:normal;font-weight:400;font-stretch:normal;font-display:swap;src:url(https://fonts.gstatic.com/s/notosans/v36/o-0mIpQlx3QUlC5A4PNB6Ryti20_6n1iPHjcz6L1SoM-jCpoiyD9A-9b6VLKzA.woff2) format("woff2");unicode-range:U+0900-097F,U+1CD0-1CF9,U+200C-200D,U+20A8,U+20B9,U+20F0,U+25CC,U+A830-A839,U+A8E0-A8FF,U+11B00-11B09}@font-face{font-family:Noto Sans;font-style:normal;font-weight:400;font-stretch:normal;font-display:swap;src:url(https://fonts.gstatic.com/s/notosans/v36/o-0mIpQlx3QUlC5A4PNB6Ryti20_6n1iPHjcz6L1SoM-jCpoiyD9A-9W6VLKzA.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Noto Sans;font-style:normal;font-weight:400;font-stretch:normal;font-display:swap;src:url(https://fonts.gstatic.com/s/notosans/v36/o-0mIpQlx3QUlC5A4PNB6Ryti20_6n1iPHjcz6L1SoM-jCpoiyD9A-9Z6VLKzA.woff2) format("woff2");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:Noto Sans;font-style:normal;font-weight:400;font-stretch:normal;font-display:swap;src:url(https://fonts.gstatic.com/s/notosans/v36/o-0mIpQlx3QUlC5A4PNB6Ryti20_6n1iPHjcz6L1SoM-jCpoiyD9A-9V6VLKzA.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Noto Sans;font-style:normal;font-weight:400;font-stretch:normal;font-display:swap;src:url(https://fonts.gstatic.com/s/notosans/v36/o-0mIpQlx3QUlC5A4PNB6Ryti20_6n1iPHjcz6L1SoM-jCpoiyD9A-9U6VLKzA.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Noto Sans;font-style:normal;font-weight:400;font-stretch:normal;font-display:swap;src:url(https://fonts.gstatic.com/s/notosans/v36/o-0mIpQlx3QUlC5A4PNB6Ryti20_6n1iPHjcz6L1SoM-jCpoiyD9A-9a6VI.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Roboto;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu72xKOzY.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Roboto;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu5mxKOzY.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Roboto;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7mxKOzY.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Roboto;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4WxKOzY.woff2) format("woff2");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:Roboto;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7WxKOzY.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Roboto;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7GxKOzY.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Roboto;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4mxK.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-cyrillic.C5lxZ8CY.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-greek-ext.CqjqNYQ-.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-greek.BBVDIX6e.woff2) format("woff2");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-vietnamese.BjW4sHH5.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-latin-ext.4ZJIpNVo.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-latin.Di8DUHzh.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-cyrillic-ext.r48I6akx.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-cyrillic.By2_1cv3.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-greek-ext.1u6EdAuj.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-greek.DJ8dCoTZ.woff2) format("woff2");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-vietnamese.BSbpV94h.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-latin-ext.CN1xVJS-.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-latin.C2AdPX0b.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Punctuation SC;font-weight:400;src:local("PingFang SC Regular"),local("Noto Sans CJK SC"),local("Microsoft YaHei");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}@font-face{font-family:Punctuation SC;font-weight:500;src:local("PingFang SC Medium"),local("Noto Sans CJK SC"),local("Microsoft YaHei");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}@font-face{font-family:Punctuation SC;font-weight:600;src:local("PingFang SC Semibold"),local("Noto Sans CJK SC Bold"),local("Microsoft YaHei Bold");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}@font-face{font-family:Punctuation SC;font-weight:700;src:local("PingFang SC Semibold"),local("Noto Sans CJK SC Bold"),local("Microsoft YaHei Bold");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}html{overflow-x:hidden}:root{--vp-c-bg: #3B4252;--vp-c-bg-elv: #434C5E;--vp-font-family-base: Itim;--vp-font-family-mono: Roboto Mono;--vp-layout-max-width: 1080px;--vp-nav-height: 48px;--vp-local-search-bg: var(--vp-c-bg-alt)}footer{color:var(--vp-c-default-1)}footer a[href^=http]:after{color:var(--vp-c-border)!important}.title{justify-content:center;border:none!important;position:unset!important;padding:0!important;width:unset!important}.title span{font-size:x-large}.search{padding-left:0;display:flex;flex-grow:0!important;padding-left:unset!important}.DocSearch-Button{margin:auto;width:unset;border:none!important}.DocSearch-Button-Placeholder{margin-top:unset!important;padding:unset!important;font-size:unset!important;font-weight:unset!important;color:unset!important;margin-right:8px}.VPNavBarMenu{align-items:flex-end}.VPNavBarMenuLink{line-height:unset!important;font-size:unset!important;font-weight:unset!important;color:unset!important}ul>li>ul{position:relative}ul>li>ul:before{position:absolute;content:"";width:2px;background:var(--vp-c-text-1);opacity:.3;left:-16px;top:8px;bottom:8px}.aside{display:none!important}.img-container{padding:15px;position:relative;height:11lh;width:fit-content;margin:auto}.img-container img{clip-path:polygon(18px 0%,100% 0,100% calc(100% - 18px),calc(100% - 18px) 100%,0 100%,0% 18px);height:100%;object-fit:contain;background:#fff}.img-container:after,.img-container:before{content:"";display:block;position:absolute;border:50px solid transparent;transform:rotate(135deg)}.img-container:after{bottom:-60px;right:-65px;box-shadow:0 7px 6px -9px #000}.img-container:before{top:-60px;left:-65px;box-shadow:0 -7px 6px -9px #000}.VPDoc{padding:0 32px!important}.VPDoc .container{position:relative}.VPDoc .container:before{content:"";position:absolute;top:0;bottom:0;left:0;width:30px;background:radial-gradient(5px 5px at 50% 50%,var(--vp-c-bg) 0%,var(--vp-c-bg) 100%,#0000 100%);background-size:100% 30px}.VPDoc .container:after{content:"";position:absolute;top:0;bottom:0;left:-15px;width:30px;z-index:1;background:linear-gradient(to bottom,transparent 11px,#333 11px,#333 13px,transparent 13px,transparent 17px,#333 17px,#333 19px,transparent 19px);background-size:100% 30px}.vp-doc a{color:unset;text-decoration:unset;font-weight:unset;text-underline-offset:unset;margin:0 -.4em;padding:.1em .4em;border-radius:.8em .3em;background:transparent;background-image:linear-gradient(to right,#ffe1000d,#ffe10059 4%,#ffe10026);-webkit-box-decoration-break:clone;box-decoration-break:clone}.vp-doc a:hover{color:unset;background-image:linear-gradient(to right,#ffe1001a,#ffe100b3 4%,#ffe1004d)}.vp-doc a[href^=http]:after{content:"";display:inline-block;margin-top:-1px;margin-left:4px;width:11px;height:11px;background:currentColor;color:var(--vp-c-text-3);flex-shrink:0;--icon: url("data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' %3E%3Cpath d='M0 0h24v24H0V0z' fill='none' /%3E%3Cpath d='M9 5v2h6.59L4 18.59 5.41 20 17 8.41V15h2V5H9z' /%3E%3C/svg%3E");-webkit-mask-image:var(--icon);mask-image:var(--icon)}.VPNav{left:96px!important;right:32px!important;width:unset!important;position:absolute!important;overflow:hidden}.wrapper{padding:0!important}.VPNavBar{background-color:unset!important}.VPNav .container{align-items:flex-end}.VPNav .content{padding:0!important}.VPNav .content-body{height:unset!important;align-items:flex-end!important;column-gap:unset!important}.VPNavBarHamburger{width:unset!important}.title{height:unset!important}a.title,.VPNavBarMenuLink,.VPNavBarSocialLinks a,.DocSearch-Button,.VPNav button{height:36px!important;border-radius:10px 10px 0 0;padding:8px 8px 16px!important;margin-bottom:-8px!important}.VPNav a:hover,.DocSearch-Button:hover,.VPNav button:hover{margin-bottom:unset!important}a.title{background-color:#0ff}.DocSearch-Button{background-color:#ff0!important}.VPNav .VPNavBarMenuLink[href="https://moddingtree.com"]{background-color:#0f0}.VPNav .VPNavBarMenuLink[href="https://incremental.social"]{background:#f0f}.VPNav button{background:red}.VPNav .VPNavBarSocialLinks [href="https://code.incremental.social/thepaperpilot"]{background:#f70}.VPNav .VPNavBarSocialLinks [href="https://matrix.to/#/@thepaperpilot:incremental.social"]{background:#3c9a3c}.VPNav .VPNavBarSocialLinks [href="https://incremental.social/u/thepaperpilot"]{background:#a75aff}.VPNav .divider{display:none!important}.VPSocialLinks{align-items:flex-end!important;margin-right:0!important}.VPSocialLinks:before{display:none}.VPNavBarExtra{display:none!important}.VPNavBarSocialLinks{display:flex!important}.VPNavScreenSocialLinks a,.VPNavScreenMenuLink,.VPNavScreenMenuLink:after{color:var(--vp-c-bg-alt)!important}@media (max-width: 500px){.VPNavBarSocialLinks{display:none!important}}@media (min-width: 501px){.VPNavScreenSocialLinks{display:none!important}}@media (max-width: 400px){.title span{width:60px}.title span:before{content:"Home ."}}.VPContent{padding-top:0!important;margin-top:var(--vp-nav-height)!important;padding-right:calc((100vw - var(--vp-layout-max-width)) / 2)!important;padding-left:calc((100vw - var(--vp-layout-max-width)) / 2)!important}@media (min-width: 960px){.VPNav{right:calc(max(0px,(100vw - var(--vp-layout-max-width)) / 2) + 32px)!important;left:calc(max(-15px,(100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width)) + 32px)!important}.VPContent{padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))!important}}.vp-doc .header-anchor{margin-left:calc(-1em - 23px)}.vp-doc .header-anchor{top:0!important}.VPSidebar{opacity:1!important;transition:.5s ease-out!important;box-shadow:0 0 10px 1px #0003!important}.VPLocalNav{position:fixed!important;border-bottom:none!important;background-color:unset!important;pointer-events:none}.VPLocalNav .container{align-items:flex-start!important;flex-direction:column!important}.VPLocalNav>.container>*{pointer-events:all}.VPLocalNav .menu{background:#7afcff;box-shadow:0 0 5px 1px #0003;margin-top:10px;height:30px;width:90px;padding:0 0 0 8px!important}.VPLocalNav button:not(.menu){background:#ff7eb9;padding:4px 30px 4px 8px;box-shadow:0 0 5px 1px #0003}.outline-marker{left:16px!important}.VPLocalNavOutlineDropdown{padding:0!important;margin-top:10px}.VPLocalNavOutlineDropdown button{padding:0!important;width:90px;height:30px}.curtain{display:none}@media (max-width: 840px){.DocSearch-Button-Keys{display:none!important}}@media (max-width: 959px){.VPSidebar{margin-left:-1000px!important;padding:30px 30px 30px 1030px!important;box-sizing:content-box;background:linear-gradient(to bottom,var(--vp-sidebar-bg-color) 29px,var(--vp-c-divider) 1px);background-size:100% 30px;line-height:30px;width:calc(100vw - 128px)}}.VPLocalNavOutlineDropdown .items{background:linear-gradient(to bottom,var(--vp-sidebar-bg-color) 29px,var(--vp-c-divider) 1px);background-size:100% 30px;top:85px;border-radius:0}.VPLocalNavOutlineDropdown ul>li>ul:before{left:0}.VPLocalNavOutlineDropdown .header,.VPLocalNavOutlineDropdown .outline{background:none!important;padding:0!important}.VPLocalNavOutlineDropdown .top-link,.VPLocalNavOutlineDropdown .outline-link{line-height:30px!important;font-size:unset!important;font-weight:unset!important}.aside-curtain{display:none!important}@media (min-width: 960px){.VPSidebar{transform:rotate(1.4deg)!important;top:1em!important;bottom:unset!important;--vp-sidebar-width: 250px !important;background:#feff9c!important;padding:30px!important;width:var(--vp-sidebar-width)!important;margin-left:max(-15px,calc((100% - (var(--vp-layout-max-width) - 60px)) / 2))!important;max-height:40vh;transition-duration:0s!important}.VPLocalNavOutlineDropdown{display:none}.VPDoc .aside{display:block!important;transform:rotate(1.4deg)!important;position:fixed;top:calc(40vh + 2em);left:0;--vp-sidebar-width: 250px !important;background:#feff9c!important;width:var(--vp-sidebar-width)!important;padding:0!important;margin-left:max(-15px,calc((100% - (var(--vp-layout-max-width) - 60px)) / 2))!important;max-height:40vh;overflow-y:auto}.VPDoc .aside-container{position:unset!important;height:unset!important;overflow:unset!important;padding-top:unset!important;width:unset!important}.VPDoc .aside-content{min-height:unset!important;padding:0!important}.VPDoc .aside-content .content{padding:30px!important}.outline-title{font-size:14px;font-weight:700!important;line-height:30px!important}.VPDoc .aside ul>li>ul:before{display:none}}.VPContent .container{background:linear-gradient(to bottom,var(--vp-sidebar-bg-color) 29px,var(--vp-c-divider) 1px);background-size:100% 30px;line-height:30px;box-shadow:0 0 10px 1px #0003!important}.VPContent .content{padding:0 30px!important}.content-container{border-left:double 7px var(--vp-c-divider);padding:30px 0 30px 8px;max-width:unset!important}article{padding-top:30px}.vp-doc .h-feed article{padding-top:0!important}.vp-doc h2+.e-content{margin-top:30px!important}.VPDoc h1,.VPDoc h2,.VPDoc h3,.VPDoc h4,.VPDoc h5,.VPDoc h6{margin:0!important;padding:0!important;line-height:30px!important}.VPDoc h1+p{margin-top:0!important}.VPDoc h2,.VPDoc h3,.VPDoc h4,.VPDoc h5,.VPDoc h6{margin-top:30px!important;margin-bottom:-30px!important;border:none!important}ul{margin:0!important}li+li{margin:0!important}.VPDoc p{padding:0!important;margin:30px 0!important;line-height:30px!important}blockquote{margin:30px 0!important}blockquote:first-child,blockquote:first-child p{margin-top:0!important}.VPDoc :has(+hr),.VPDoc :has(+h2),.VPDoc :has(+h3),.VPDoc :has(+h4),.VPDoc :has(+h5),.VPDoc :has(+h6),.VPDoc :has(+ul){margin-bottom:0!important}hr{margin-top:-3px!important;margin-bottom:-7px!important;border-top-style:solid!important;border-top-width:10px!important;border-image:url(/button.svg) 10 10 10 10 stretch stretch!important;height:0px!important}.text{line-height:30px!important;padding:0!important;margin:0!important}.group{padding-top:0!important}.group+.group{border-top-style:solid!important;border-top-width:10px!important;border-image:url(/button.svg) 10 10 10 10 stretch stretch!important;padding-top:23px!important;margin-top:-3px!important}table{margin:30px 0!important}#app .vp-doc tr{background-color:var(--vp-c-gray-2)}#app .vp-doc tr:nth-child(2n){background-color:var(--vp-c-bg-soft)}#app .vp-doc th,#app .vp-doc td{font-size:unset!important;font-weight:unset!important;color:unset!important;padding:0 8px!important;line-height:29px}.VPSidebarItem{padding-bottom:0!important}p:last-child{margin-bottom:0!important}.hero{width:60%;margin:auto}footer img{height:1lh;display:inline;border-radius:50%;margin:0 .25em;vertical-align:bottom}@property --anim-bg{syntax: ""; initial-value: transparent; inherits: false;}@keyframes vp-nolebase-highlight-targeted-heading-animation{0%{--anim-bg: transparent}10%,35%{--anim-bg: var(--vp-c-brand-soft)}99%{--anim-bg: transparent}to{--anim-bg: transparent}}.VPNolebaseHighlightTargetedHeadingAnimated{animation:vp-nolebase-highlight-targeted-heading-animation 1.5s ease-in-out;background:linear-gradient(0deg,var(--anim-bg) 55%,transparent 45%) repeat-x}.title-icon{line-height:30px}.excerpt{margin:8px 0!important;background:var(--docsearch-searchbox-background)}.excerpt-gradient-top{background:var(--docsearch-searchbox-background)!important;opacity:.5;clip-path:polygon(0% 0%,5% 100%,10% 0%,15% 100%,20% 0%,25% 100%,30% 0%,35% 100%,40% 0%,45% 100%,50% 0%,55% 100%,60% 0%,65% 100%,70% 0%,75% 100%,80% 0%,85% 100%,90% 0%,95% 100%,100% 0%);transform:translateY(-7px) rotate(180deg)}.excerpt-gradient-bottom{background:var(--docsearch-searchbox-background)!important;opacity:.5;clip-path:polygon(0% 0%,5% 100%,10% 0%,15% 100%,20% 0%,25% 100%,30% 0%,35% 100%,40% 0%,45% 100%,50% 0%,55% 100%,60% 0%,65% 100%,70% 0%,75% 100%,80% 0%,85% 100%,90% 0%,95% 100%,100% 0%);transform:translateY(7px)}.selected .excerpt-gradient-top,.selected .excerpt-gradient-bottom{opacity:1}.vp-doc details{border-bottom:solid 1px var(--vp-c-border)!important;margin-bottom:-1px!important}.vp-doc details a{margin-right:8px!important}.vp-doc summary{margin:29px 0 0!important;border-top:solid 1px var(--vp-c-border)!important;cursor:pointer!important}.background[data-v-ebc087d8]{position:fixed;top:0;left:0;right:0;bottom:0;z-index:-1;overflow:hidden}footer[data-v-ebc087d8]{padding:2em;z-index:26;position:relative;font-size:small;background:var(--vp-c-bg-elv)}.hero-wrapper[data-v-a285fdae]{height:16lh;position:relative}@media (max-width: 700px){.hero-wrapper[data-v-a285fdae]{height:12lh}}@media (max-width: 500px){.hero-wrapper[data-v-a285fdae]{height:10lh}}@media (max-width: 400px){.hero-wrapper[data-v-a285fdae]{height:9lh}}.hero[data-v-a285fdae]{height:80%;width:unset;margin:auto;position:absolute;right:50%;bottom:0;transform:translate(calc(50% + var(--x-offset)));animation:bob-a285fdae 5s ease-in-out infinite}svg[data-v-a285fdae]{display:none}@keyframes bob-a285fdae{0%{transform:translate(calc(50% + var(--x-offset)),-10%)}50%{transform:translate(calc(50% + var(--x-offset)),10%)}to{transform:translate(calc(50% + var(--x-offset)),-10%)}}.VPLocalSearchBox[data-v-639d7ab9]{position:fixed;z-index:100;top:0;right:0;bottom:0;left:0;display:flex}.backdrop[data-v-639d7ab9]{position:absolute;top:0;right:0;bottom:0;left:0;background:var(--vp-backdrop-bg-color);transition:opacity .5s}.shell[data-v-639d7ab9]{position:relative;padding:12px;margin:64px auto;display:flex;flex-direction:column;gap:16px;background:var(--vp-local-search-bg);width:min(100vw - 60px,900px);height:min-content;max-height:min(100vh - 128px,900px);border-radius:6px}@media (max-width: 767px){.shell[data-v-639d7ab9]{margin:0;width:100vw;height:100vh;max-height:none;border-radius:0}}.search-bar[data-v-639d7ab9]{border:1px solid var(--vp-c-divider);border-radius:4px;display:flex;align-items:center;padding:0 12px;cursor:text}@media (max-width: 767px){.search-bar[data-v-639d7ab9]{padding:0 8px}}.search-bar[data-v-639d7ab9]:focus-within{border-color:var(--vp-c-brand-1)}.local-search-icon[data-v-639d7ab9]{display:block;font-size:18px}.navigate-icon[data-v-639d7ab9]{display:block;font-size:14px}.search-icon[data-v-639d7ab9]{margin:8px}@media (max-width: 767px){.search-icon[data-v-639d7ab9]{display:none}}.search-input[data-v-639d7ab9]{padding:6px 12px;font-size:inherit;width:100%}@media (max-width: 767px){.search-input[data-v-639d7ab9]{padding:6px 4px}}.search-actions[data-v-639d7ab9]{display:flex;gap:4px}@media (any-pointer: coarse){.search-actions[data-v-639d7ab9]{gap:8px}}@media (min-width: 769px){.search-actions.before[data-v-639d7ab9]{display:none}}.search-actions button[data-v-639d7ab9]{padding:8px}.search-actions button[data-v-639d7ab9]:not([disabled]):hover,.toggle-layout-button.detailed-list[data-v-639d7ab9]{color:var(--vp-c-brand-1)}.search-actions button.clear-button[data-v-639d7ab9]:disabled{opacity:.37}.search-keyboard-shortcuts[data-v-639d7ab9]{font-size:.8rem;opacity:75%;display:flex;flex-wrap:wrap;gap:16px;line-height:14px}.search-keyboard-shortcuts span[data-v-639d7ab9]{display:flex;align-items:center;gap:4px}@media (max-width: 767px){.search-keyboard-shortcuts[data-v-639d7ab9]{display:none}}.search-keyboard-shortcuts kbd[data-v-639d7ab9]{background:#8080801a;border-radius:4px;padding:3px 6px;min-width:24px;display:inline-block;text-align:center;vertical-align:middle;border:1px solid rgba(128,128,128,.15);box-shadow:0 2px 2px #0000001a}.results[data-v-639d7ab9]{display:flex;flex-direction:column;gap:6px;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain}.result[data-v-639d7ab9]{display:flex;align-items:center;gap:8px;border-radius:4px;transition:none;line-height:1rem;border:solid 2px var(--vp-local-search-result-border);outline:none}.result>div[data-v-639d7ab9]{margin:12px;width:100%;overflow:hidden}@media (max-width: 767px){.result>div[data-v-639d7ab9]{margin:8px}}.titles[data-v-639d7ab9]{display:flex;flex-wrap:wrap;gap:4px;position:relative;z-index:1001;padding:2px 0}.title[data-v-639d7ab9]{display:flex;align-items:center;gap:4px}.title.main[data-v-639d7ab9]{font-weight:500}.title-icon[data-v-639d7ab9]{opacity:.5;font-weight:500;color:var(--vp-c-brand-1)}.title svg[data-v-639d7ab9]{opacity:.5}.result.selected[data-v-639d7ab9]{--vp-local-search-result-bg: var(--vp-local-search-result-selected-bg);border-color:var(--vp-local-search-result-selected-border)}.excerpt-wrapper[data-v-639d7ab9]{position:relative}.excerpt[data-v-639d7ab9]{opacity:75%;pointer-events:none;max-height:140px;overflow:hidden;position:relative;opacity:.5;margin-top:4px}.result.selected .excerpt[data-v-639d7ab9]{opacity:1}.excerpt[data-v-639d7ab9] *{font-size:.8rem!important;line-height:130%!important}.titles[data-v-639d7ab9] mark,.excerpt[data-v-639d7ab9] mark{background-color:var(--vp-local-search-highlight-bg);color:var(--vp-local-search-highlight-text);border-radius:2px;padding:0 2px}.excerpt[data-v-639d7ab9] .vp-code-group .tabs{display:none}.excerpt[data-v-639d7ab9] .vp-code-group div[class*=language-]{border-radius:8px!important}.excerpt-gradient-bottom[data-v-639d7ab9]{position:absolute;bottom:-1px;left:0;width:100%;height:8px;background:linear-gradient(transparent,var(--vp-local-search-result-bg));z-index:1000}.excerpt-gradient-top[data-v-639d7ab9]{position:absolute;top:-1px;left:0;width:100%;height:8px;background:linear-gradient(var(--vp-local-search-result-bg),transparent);z-index:1000}.result.selected .titles[data-v-639d7ab9],.result.selected .title-icon[data-v-639d7ab9]{color:var(--vp-c-brand-1)!important}.no-results[data-v-639d7ab9]{font-size:.9rem;text-align:center;padding:12px}svg[data-v-639d7ab9]{flex:none} +:root{--vp-c-white: #ffffff;--vp-c-black: #000000;--vp-c-neutral: var(--vp-c-black);--vp-c-neutral-inverse: var(--vp-c-white)}.dark{--vp-c-neutral: var(--vp-c-white);--vp-c-neutral-inverse: var(--vp-c-black)}:root{--vp-c-gray-1: #dddde3;--vp-c-gray-2: #e4e4e9;--vp-c-gray-3: #ebebef;--vp-c-gray-soft: rgba(142, 150, 170, .14);--vp-c-indigo-1: #3451b2;--vp-c-indigo-2: #3a5ccc;--vp-c-indigo-3: #5672cd;--vp-c-indigo-soft: rgba(100, 108, 255, .14);--vp-c-purple-1: #6f42c1;--vp-c-purple-2: #7e4cc9;--vp-c-purple-3: #8e5cd9;--vp-c-purple-soft: rgba(159, 122, 234, .14);--vp-c-green-1: #18794e;--vp-c-green-2: #299764;--vp-c-green-3: #30a46c;--vp-c-green-soft: rgba(16, 185, 129, .14);--vp-c-yellow-1: #915930;--vp-c-yellow-2: #946300;--vp-c-yellow-3: #9f6a00;--vp-c-yellow-soft: rgba(234, 179, 8, .14);--vp-c-red-1: #b8272c;--vp-c-red-2: #d5393e;--vp-c-red-3: #e0575b;--vp-c-red-soft: rgba(244, 63, 94, .14);--vp-c-sponsor: #db2777}.dark{--vp-c-gray-1: #515c67;--vp-c-gray-2: #414853;--vp-c-gray-3: #32363f;--vp-c-gray-soft: rgba(101, 117, 133, .16);--vp-c-indigo-1: #a8b1ff;--vp-c-indigo-2: #5c73e7;--vp-c-indigo-3: #3e63dd;--vp-c-indigo-soft: rgba(100, 108, 255, .16);--vp-c-purple-1: #c8abfa;--vp-c-purple-2: #a879e6;--vp-c-purple-3: #8e5cd9;--vp-c-purple-soft: rgba(159, 122, 234, .16);--vp-c-green-1: #3dd68c;--vp-c-green-2: #30a46c;--vp-c-green-3: #298459;--vp-c-green-soft: rgba(16, 185, 129, .16);--vp-c-yellow-1: #f9b44e;--vp-c-yellow-2: #da8b17;--vp-c-yellow-3: #a46a0a;--vp-c-yellow-soft: rgba(234, 179, 8, .16);--vp-c-red-1: #f66f81;--vp-c-red-2: #f14158;--vp-c-red-3: #b62a3c;--vp-c-red-soft: rgba(244, 63, 94, .16)}:root{--vp-c-bg: #ffffff;--vp-c-bg-alt: #f6f6f7;--vp-c-bg-elv: #ffffff;--vp-c-bg-soft: #f6f6f7}.dark{--vp-c-bg: #1b1b1f;--vp-c-bg-alt: #161618;--vp-c-bg-elv: #202127;--vp-c-bg-soft: #202127}:root{--vp-c-border: #c2c2c4;--vp-c-divider: #e2e2e3;--vp-c-gutter: #e2e2e3}.dark{--vp-c-border: #3c3f44;--vp-c-divider: #2e2e32;--vp-c-gutter: #000000}:root{--vp-c-text-1: rgba(60, 60, 67);--vp-c-text-2: rgba(60, 60, 67, .78);--vp-c-text-3: rgba(60, 60, 67, .56)}.dark{--vp-c-text-1: rgba(255, 255, 245, .86);--vp-c-text-2: rgba(235, 235, 245, .6);--vp-c-text-3: rgba(235, 235, 245, .38)}:root{--vp-c-default-1: var(--vp-c-gray-1);--vp-c-default-2: var(--vp-c-gray-2);--vp-c-default-3: var(--vp-c-gray-3);--vp-c-default-soft: var(--vp-c-gray-soft);--vp-c-brand-1: var(--vp-c-indigo-1);--vp-c-brand-2: var(--vp-c-indigo-2);--vp-c-brand-3: var(--vp-c-indigo-3);--vp-c-brand-soft: var(--vp-c-indigo-soft);--vp-c-brand: var(--vp-c-brand-1);--vp-c-tip-1: var(--vp-c-brand-1);--vp-c-tip-2: var(--vp-c-brand-2);--vp-c-tip-3: var(--vp-c-brand-3);--vp-c-tip-soft: var(--vp-c-brand-soft);--vp-c-note-1: var(--vp-c-brand-1);--vp-c-note-2: var(--vp-c-brand-2);--vp-c-note-3: var(--vp-c-brand-3);--vp-c-note-soft: var(--vp-c-brand-soft);--vp-c-success-1: var(--vp-c-green-1);--vp-c-success-2: var(--vp-c-green-2);--vp-c-success-3: var(--vp-c-green-3);--vp-c-success-soft: var(--vp-c-green-soft);--vp-c-important-1: var(--vp-c-purple-1);--vp-c-important-2: var(--vp-c-purple-2);--vp-c-important-3: var(--vp-c-purple-3);--vp-c-important-soft: var(--vp-c-purple-soft);--vp-c-warning-1: var(--vp-c-yellow-1);--vp-c-warning-2: var(--vp-c-yellow-2);--vp-c-warning-3: var(--vp-c-yellow-3);--vp-c-warning-soft: var(--vp-c-yellow-soft);--vp-c-danger-1: var(--vp-c-red-1);--vp-c-danger-2: var(--vp-c-red-2);--vp-c-danger-3: var(--vp-c-red-3);--vp-c-danger-soft: var(--vp-c-red-soft);--vp-c-caution-1: var(--vp-c-red-1);--vp-c-caution-2: var(--vp-c-red-2);--vp-c-caution-3: var(--vp-c-red-3);--vp-c-caution-soft: var(--vp-c-red-soft)}:root{--vp-font-family-base: "Inter", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--vp-font-family-mono: ui-monospace, "Menlo", "Monaco", "Consolas", "Liberation Mono", "Courier New", monospace;font-optical-sizing:auto}:root:where(:lang(zh)){--vp-font-family-base: "Punctuation SC", "Inter", ui-sans-serif, system-ui, "PingFang SC", "Noto Sans CJK SC", "Noto Sans SC", "Heiti SC", "Microsoft YaHei", "DengXian", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"}:root{--vp-shadow-1: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 2px rgba(0, 0, 0, .06);--vp-shadow-2: 0 3px 12px rgba(0, 0, 0, .07), 0 1px 4px rgba(0, 0, 0, .07);--vp-shadow-3: 0 12px 32px rgba(0, 0, 0, .1), 0 2px 6px rgba(0, 0, 0, .08);--vp-shadow-4: 0 14px 44px rgba(0, 0, 0, .12), 0 3px 9px rgba(0, 0, 0, .12);--vp-shadow-5: 0 18px 56px rgba(0, 0, 0, .16), 0 4px 12px rgba(0, 0, 0, .16)}:root{--vp-z-index-footer: 10;--vp-z-index-local-nav: 20;--vp-z-index-nav: 30;--vp-z-index-layout-top: 40;--vp-z-index-backdrop: 50;--vp-z-index-sidebar: 60}@media (min-width: 960px){:root{--vp-z-index-sidebar: 25}}:root{--vp-layout-max-width: 1440px}:root{--vp-header-anchor-symbol: "#"}:root{--vp-code-line-height: 1.7;--vp-code-font-size: .875em;--vp-code-color: var(--vp-c-brand-1);--vp-code-link-color: var(--vp-c-brand-1);--vp-code-link-hover-color: var(--vp-c-brand-2);--vp-code-bg: var(--vp-c-default-soft);--vp-code-block-color: var(--vp-c-text-2);--vp-code-block-bg: var(--vp-c-bg-alt);--vp-code-block-divider-color: var(--vp-c-gutter);--vp-code-lang-color: var(--vp-c-text-3);--vp-code-line-highlight-color: var(--vp-c-default-soft);--vp-code-line-number-color: var(--vp-c-text-3);--vp-code-line-diff-add-color: var(--vp-c-success-soft);--vp-code-line-diff-add-symbol-color: var(--vp-c-success-1);--vp-code-line-diff-remove-color: var(--vp-c-danger-soft);--vp-code-line-diff-remove-symbol-color: var(--vp-c-danger-1);--vp-code-line-warning-color: var(--vp-c-warning-soft);--vp-code-line-error-color: var(--vp-c-danger-soft);--vp-code-copy-code-border-color: var(--vp-c-divider);--vp-code-copy-code-bg: var(--vp-c-bg-soft);--vp-code-copy-code-hover-border-color: var(--vp-c-divider);--vp-code-copy-code-hover-bg: var(--vp-c-bg);--vp-code-copy-code-active-text: var(--vp-c-text-2);--vp-code-copy-copied-text-content: "Copied";--vp-code-tab-divider: var(--vp-code-block-divider-color);--vp-code-tab-text-color: var(--vp-c-text-2);--vp-code-tab-bg: var(--vp-code-block-bg);--vp-code-tab-hover-text-color: var(--vp-c-text-1);--vp-code-tab-active-text-color: var(--vp-c-text-1);--vp-code-tab-active-bar-color: var(--vp-c-brand-1)}:root{--vp-button-brand-border: transparent;--vp-button-brand-text: var(--vp-c-white);--vp-button-brand-bg: var(--vp-c-brand-3);--vp-button-brand-hover-border: transparent;--vp-button-brand-hover-text: var(--vp-c-white);--vp-button-brand-hover-bg: var(--vp-c-brand-2);--vp-button-brand-active-border: transparent;--vp-button-brand-active-text: var(--vp-c-white);--vp-button-brand-active-bg: var(--vp-c-brand-1);--vp-button-alt-border: transparent;--vp-button-alt-text: var(--vp-c-text-1);--vp-button-alt-bg: var(--vp-c-default-3);--vp-button-alt-hover-border: transparent;--vp-button-alt-hover-text: var(--vp-c-text-1);--vp-button-alt-hover-bg: var(--vp-c-default-2);--vp-button-alt-active-border: transparent;--vp-button-alt-active-text: var(--vp-c-text-1);--vp-button-alt-active-bg: var(--vp-c-default-1);--vp-button-sponsor-border: var(--vp-c-text-2);--vp-button-sponsor-text: var(--vp-c-text-2);--vp-button-sponsor-bg: transparent;--vp-button-sponsor-hover-border: var(--vp-c-sponsor);--vp-button-sponsor-hover-text: var(--vp-c-sponsor);--vp-button-sponsor-hover-bg: transparent;--vp-button-sponsor-active-border: var(--vp-c-sponsor);--vp-button-sponsor-active-text: var(--vp-c-sponsor);--vp-button-sponsor-active-bg: transparent}:root{--vp-custom-block-font-size: 14px;--vp-custom-block-code-font-size: 13px;--vp-custom-block-info-border: transparent;--vp-custom-block-info-text: var(--vp-c-text-1);--vp-custom-block-info-bg: var(--vp-c-default-soft);--vp-custom-block-info-code-bg: var(--vp-c-default-soft);--vp-custom-block-note-border: transparent;--vp-custom-block-note-text: var(--vp-c-text-1);--vp-custom-block-note-bg: var(--vp-c-default-soft);--vp-custom-block-note-code-bg: var(--vp-c-default-soft);--vp-custom-block-tip-border: transparent;--vp-custom-block-tip-text: var(--vp-c-text-1);--vp-custom-block-tip-bg: var(--vp-c-tip-soft);--vp-custom-block-tip-code-bg: var(--vp-c-tip-soft);--vp-custom-block-important-border: transparent;--vp-custom-block-important-text: var(--vp-c-text-1);--vp-custom-block-important-bg: var(--vp-c-important-soft);--vp-custom-block-important-code-bg: var(--vp-c-important-soft);--vp-custom-block-warning-border: transparent;--vp-custom-block-warning-text: var(--vp-c-text-1);--vp-custom-block-warning-bg: var(--vp-c-warning-soft);--vp-custom-block-warning-code-bg: var(--vp-c-warning-soft);--vp-custom-block-danger-border: transparent;--vp-custom-block-danger-text: var(--vp-c-text-1);--vp-custom-block-danger-bg: var(--vp-c-danger-soft);--vp-custom-block-danger-code-bg: var(--vp-c-danger-soft);--vp-custom-block-caution-border: transparent;--vp-custom-block-caution-text: var(--vp-c-text-1);--vp-custom-block-caution-bg: var(--vp-c-caution-soft);--vp-custom-block-caution-code-bg: var(--vp-c-caution-soft);--vp-custom-block-details-border: var(--vp-custom-block-info-border);--vp-custom-block-details-text: var(--vp-custom-block-info-text);--vp-custom-block-details-bg: var(--vp-custom-block-info-bg);--vp-custom-block-details-code-bg: var(--vp-custom-block-info-code-bg)}:root{--vp-input-border-color: var(--vp-c-border);--vp-input-bg-color: var(--vp-c-bg-alt);--vp-input-switch-bg-color: var(--vp-c-default-soft)}:root{--vp-nav-height: 64px;--vp-nav-bg-color: var(--vp-c-bg);--vp-nav-screen-bg-color: var(--vp-c-bg);--vp-nav-logo-height: 24px}.hide-nav{--vp-nav-height: 0px}.hide-nav .VPSidebar{--vp-nav-height: 22px}:root{--vp-local-nav-bg-color: var(--vp-c-bg)}:root{--vp-sidebar-width: 272px;--vp-sidebar-bg-color: var(--vp-c-bg-alt)}:root{--vp-backdrop-bg-color: rgba(0, 0, 0, .6)}:root{--vp-home-hero-name-color: var(--vp-c-brand-1);--vp-home-hero-name-background: transparent;--vp-home-hero-image-background-image: none;--vp-home-hero-image-filter: none}:root{--vp-badge-info-border: transparent;--vp-badge-info-text: var(--vp-c-text-2);--vp-badge-info-bg: var(--vp-c-default-soft);--vp-badge-tip-border: transparent;--vp-badge-tip-text: var(--vp-c-tip-1);--vp-badge-tip-bg: var(--vp-c-tip-soft);--vp-badge-warning-border: transparent;--vp-badge-warning-text: var(--vp-c-warning-1);--vp-badge-warning-bg: var(--vp-c-warning-soft);--vp-badge-danger-border: transparent;--vp-badge-danger-text: var(--vp-c-danger-1);--vp-badge-danger-bg: var(--vp-c-danger-soft)}:root{--vp-carbon-ads-text-color: var(--vp-c-text-1);--vp-carbon-ads-poweredby-color: var(--vp-c-text-2);--vp-carbon-ads-bg-color: var(--vp-c-bg-soft);--vp-carbon-ads-hover-text-color: var(--vp-c-brand-1);--vp-carbon-ads-hover-poweredby-color: var(--vp-c-text-1)}:root{--vp-local-search-bg: var(--vp-c-bg);--vp-local-search-result-bg: var(--vp-c-bg);--vp-local-search-result-border: var(--vp-c-divider);--vp-local-search-result-selected-bg: var(--vp-c-bg);--vp-local-search-result-selected-border: var(--vp-c-brand-1);--vp-local-search-highlight-bg: var(--vp-c-brand-1);--vp-local-search-highlight-text: var(--vp-c-neutral-inverse)}@media (prefers-reduced-motion: reduce){*,:before,:after{animation-delay:-1ms!important;animation-duration:1ms!important;animation-iteration-count:1!important;background-attachment:initial!important;scroll-behavior:auto!important;transition-duration:0s!important;transition-delay:0s!important}}*,:before,:after{box-sizing:border-box}html{line-height:1.4;font-size:16px;-webkit-text-size-adjust:100%}html.dark{color-scheme:dark}body{margin:0;width:100%;min-width:320px;min-height:100vh;line-height:24px;font-family:var(--vp-font-family-base);font-size:16px;font-weight:400;color:var(--vp-c-text-1);background-color:var(--vp-c-bg);font-synthesis:style;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}main{display:block}h1,h2,h3,h4,h5,h6{margin:0;line-height:24px;font-size:16px;font-weight:400}p{margin:0}strong,b{font-weight:600}a,area,button,[role=button],input,label,select,summary,textarea{touch-action:manipulation}a{color:inherit;text-decoration:inherit}ol,ul{list-style:none;margin:0;padding:0}blockquote{margin:0}pre,code,kbd,samp{font-family:var(--vp-font-family-mono)}img,svg,video,canvas,audio,iframe,embed,object{display:block}figure{margin:0}img,video{max-width:100%;height:auto}button,input,optgroup,select,textarea{border:0;padding:0;line-height:inherit;color:inherit}button{padding:0;font-family:inherit;background-color:transparent;background-image:none}button:enabled,[role=button]:enabled{cursor:pointer}button:focus,button:focus-visible{outline:1px dotted;outline:4px auto -webkit-focus-ring-color}button:focus:not(:focus-visible){outline:none!important}input:focus,textarea:focus,select:focus{outline:none}table{border-collapse:collapse}input{background-color:transparent}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:var(--vp-c-text-3)}input::-ms-input-placeholder,textarea::-ms-input-placeholder{color:var(--vp-c-text-3)}input::placeholder,textarea::placeholder{color:var(--vp-c-text-3)}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}input[type=number]{-moz-appearance:textfield}textarea{resize:vertical}select{-webkit-appearance:none}fieldset{margin:0;padding:0}h1,h2,h3,h4,h5,h6,li,p{overflow-wrap:break-word}vite-error-overlay{z-index:9999}mjx-container{display:inline-block;margin:auto 2px -2px}mjx-container>svg{display:inline-block;margin:auto}[class^=vpi-],[class*=" vpi-"],.vp-icon{width:1em;height:1em}[class^=vpi-].bg,[class*=" vpi-"].bg,.vp-icon.bg{background-size:100% 100%;background-color:transparent}[class^=vpi-]:not(.bg),[class*=" vpi-"]:not(.bg),.vp-icon:not(.bg){-webkit-mask:var(--icon) no-repeat;mask:var(--icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit}.vpi-align-left{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M21 6H3M15 12H3M17 18H3'/%3E%3C/svg%3E")}.vpi-arrow-right,.vpi-arrow-down,.vpi-arrow-left,.vpi-arrow-up{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h14M12 5l7 7-7 7'/%3E%3C/svg%3E")}.vpi-chevron-right,.vpi-chevron-down,.vpi-chevron-left,.vpi-chevron-up{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E")}.vpi-chevron-down,.vpi-arrow-down{transform:rotate(90deg)}.vpi-chevron-left,.vpi-arrow-left{transform:rotate(180deg)}.vpi-chevron-up,.vpi-arrow-up{transform:rotate(-90deg)}.vpi-square-pen{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7'/%3E%3Cpath d='M18.375 2.625a2.121 2.121 0 1 1 3 3L12 15l-4 1 1-4Z'/%3E%3C/svg%3E")}.vpi-plus{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h14M12 5v14'/%3E%3C/svg%3E")}.vpi-sun{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='4'/%3E%3Cpath d='M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41'/%3E%3C/svg%3E")}.vpi-moon{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z'/%3E%3C/svg%3E")}.vpi-more-horizontal{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='1'/%3E%3Ccircle cx='19' cy='12' r='1'/%3E%3Ccircle cx='5' cy='12' r='1'/%3E%3C/svg%3E")}.vpi-languages{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m5 8 6 6M4 14l6-6 2-3M2 5h12M7 2h1M22 22l-5-10-5 10M14 18h6'/%3E%3C/svg%3E")}.vpi-heart{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z'/%3E%3C/svg%3E")}.vpi-search{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E")}.vpi-layout-list{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='7' height='7' x='3' y='3' rx='1'/%3E%3Crect width='7' height='7' x='3' y='14' rx='1'/%3E%3Cpath d='M14 4h7M14 9h7M14 15h7M14 20h7'/%3E%3C/svg%3E")}.vpi-delete{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M20 5H9l-7 7 7 7h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2ZM18 9l-6 6M12 9l6 6'/%3E%3C/svg%3E")}.vpi-corner-down-left{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m9 10-5 5 5 5'/%3E%3Cpath d='M20 4v7a4 4 0 0 1-4 4H4'/%3E%3C/svg%3E")}:root{--vp-icon-copy: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3C/svg%3E");--vp-icon-copied: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3Cpath d='m9 14 2 2 4-4'/%3E%3C/svg%3E")}.vpi-social-discord{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418Z'/%3E%3C/svg%3E")}.vpi-social-facebook{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9.101 23.691v-7.98H6.627v-3.667h2.474v-1.58c0-4.085 1.848-5.978 5.858-5.978.401 0 .955.042 1.468.103a8.68 8.68 0 0 1 1.141.195v3.325a8.623 8.623 0 0 0-.653-.036 26.805 26.805 0 0 0-.733-.009c-.707 0-1.259.096-1.675.309a1.686 1.686 0 0 0-.679.622c-.258.42-.374.995-.374 1.752v1.297h3.919l-.386 2.103-.287 1.564h-3.246v8.245C19.396 23.238 24 18.179 24 12.044c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.628 3.874 10.35 9.101 11.647Z'/%3E%3C/svg%3E")}.vpi-social-github{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")}.vpi-social-instagram{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7.03.084c-1.277.06-2.149.264-2.91.563a5.874 5.874 0 0 0-2.124 1.388 5.878 5.878 0 0 0-1.38 2.127C.321 4.926.12 5.8.064 7.076.008 8.354-.005 8.764.001 12.023c.007 3.259.021 3.667.083 4.947.061 1.277.264 2.149.563 2.911.308.789.72 1.457 1.388 2.123a5.872 5.872 0 0 0 2.129 1.38c.763.295 1.636.496 2.913.552 1.278.056 1.689.069 4.947.063 3.257-.007 3.668-.021 4.947-.082 1.28-.06 2.147-.265 2.91-.563a5.881 5.881 0 0 0 2.123-1.388 5.881 5.881 0 0 0 1.38-2.129c.295-.763.496-1.636.551-2.912.056-1.28.07-1.69.063-4.948-.006-3.258-.02-3.667-.081-4.947-.06-1.28-.264-2.148-.564-2.911a5.892 5.892 0 0 0-1.387-2.123 5.857 5.857 0 0 0-2.128-1.38C19.074.322 18.202.12 16.924.066 15.647.009 15.236-.006 11.977 0 8.718.008 8.31.021 7.03.084m.14 21.693c-1.17-.05-1.805-.245-2.228-.408a3.736 3.736 0 0 1-1.382-.895 3.695 3.695 0 0 1-.9-1.378c-.165-.423-.363-1.058-.417-2.228-.06-1.264-.072-1.644-.08-4.848-.006-3.204.006-3.583.061-4.848.05-1.169.246-1.805.408-2.228.216-.561.477-.96.895-1.382a3.705 3.705 0 0 1 1.379-.9c.423-.165 1.057-.361 2.227-.417 1.265-.06 1.644-.072 4.848-.08 3.203-.006 3.583.006 4.85.062 1.168.05 1.804.244 2.227.408.56.216.96.475 1.382.895.421.42.681.817.9 1.378.165.422.362 1.056.417 2.227.06 1.265.074 1.645.08 4.848.005 3.203-.006 3.583-.061 4.848-.051 1.17-.245 1.805-.408 2.23-.216.56-.477.96-.896 1.38a3.705 3.705 0 0 1-1.378.9c-.422.165-1.058.362-2.226.418-1.266.06-1.645.072-4.85.079-3.204.007-3.582-.006-4.848-.06m9.783-16.192a1.44 1.44 0 1 0 1.437-1.442 1.44 1.44 0 0 0-1.437 1.442M5.839 12.012a6.161 6.161 0 1 0 12.323-.024 6.162 6.162 0 0 0-12.323.024M8 12.008A4 4 0 1 1 12.008 16 4 4 0 0 1 8 12.008'/%3E%3C/svg%3E")}.vpi-social-linkedin{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 0 1-2.063-2.065 2.064 2.064 0 1 1 2.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z'/%3E%3C/svg%3E")}.vpi-social-mastodon{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z'/%3E%3C/svg%3E")}.vpi-social-npm{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M1.763 0C.786 0 0 .786 0 1.763v20.474C0 23.214.786 24 1.763 24h20.474c.977 0 1.763-.786 1.763-1.763V1.763C24 .786 23.214 0 22.237 0zM5.13 5.323l13.837.019-.009 13.836h-3.464l.01-10.382h-3.456L12.04 19.17H5.113z'/%3E%3C/svg%3E")}.vpi-social-slack{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52zm1.271 0a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313zM8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834zm0 1.271a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312zm10.122 2.521a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834zm-1.268 0a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.165 0a2.528 2.528 0 0 1 2.523 2.522v6.312zm-2.523 10.122a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.165 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52zm0-1.268a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.313A2.527 2.527 0 0 1 24 15.165a2.528 2.528 0 0 1-2.522 2.523h-6.313z'/%3E%3C/svg%3E")}.vpi-social-twitter,.vpi-social-x{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z'/%3E%3C/svg%3E")}.vpi-social-youtube{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z'/%3E%3C/svg%3E")}.visually-hidden{position:absolute;width:1px;height:1px;white-space:nowrap;clip:rect(0 0 0 0);clip-path:inset(50%);overflow:hidden}.custom-block{border:1px solid transparent;border-radius:8px;padding:16px 16px 8px;line-height:24px;font-size:var(--vp-custom-block-font-size);color:var(--vp-c-text-2)}.custom-block.info{border-color:var(--vp-custom-block-info-border);color:var(--vp-custom-block-info-text);background-color:var(--vp-custom-block-info-bg)}.custom-block.info a,.custom-block.info code{color:var(--vp-c-brand-1)}.custom-block.info a:hover,.custom-block.info a:hover>code{color:var(--vp-c-brand-2)}.custom-block.info code{background-color:var(--vp-custom-block-info-code-bg)}.custom-block.note{border-color:var(--vp-custom-block-note-border);color:var(--vp-custom-block-note-text);background-color:var(--vp-custom-block-note-bg)}.custom-block.note a,.custom-block.note code{color:var(--vp-c-brand-1)}.custom-block.note a:hover,.custom-block.note a:hover>code{color:var(--vp-c-brand-2)}.custom-block.note code{background-color:var(--vp-custom-block-note-code-bg)}.custom-block.tip{border-color:var(--vp-custom-block-tip-border);color:var(--vp-custom-block-tip-text);background-color:var(--vp-custom-block-tip-bg)}.custom-block.tip a,.custom-block.tip code{color:var(--vp-c-tip-1)}.custom-block.tip a:hover,.custom-block.tip a:hover>code{color:var(--vp-c-tip-2)}.custom-block.tip code{background-color:var(--vp-custom-block-tip-code-bg)}.custom-block.important{border-color:var(--vp-custom-block-important-border);color:var(--vp-custom-block-important-text);background-color:var(--vp-custom-block-important-bg)}.custom-block.important a,.custom-block.important code{color:var(--vp-c-important-1)}.custom-block.important a:hover,.custom-block.important a:hover>code{color:var(--vp-c-important-2)}.custom-block.important code{background-color:var(--vp-custom-block-important-code-bg)}.custom-block.warning{border-color:var(--vp-custom-block-warning-border);color:var(--vp-custom-block-warning-text);background-color:var(--vp-custom-block-warning-bg)}.custom-block.warning a,.custom-block.warning code{color:var(--vp-c-warning-1)}.custom-block.warning a:hover,.custom-block.warning a:hover>code{color:var(--vp-c-warning-2)}.custom-block.warning code{background-color:var(--vp-custom-block-warning-code-bg)}.custom-block.danger{border-color:var(--vp-custom-block-danger-border);color:var(--vp-custom-block-danger-text);background-color:var(--vp-custom-block-danger-bg)}.custom-block.danger a,.custom-block.danger code{color:var(--vp-c-danger-1)}.custom-block.danger a:hover,.custom-block.danger a:hover>code{color:var(--vp-c-danger-2)}.custom-block.danger code{background-color:var(--vp-custom-block-danger-code-bg)}.custom-block.caution{border-color:var(--vp-custom-block-caution-border);color:var(--vp-custom-block-caution-text);background-color:var(--vp-custom-block-caution-bg)}.custom-block.caution a,.custom-block.caution code{color:var(--vp-c-caution-1)}.custom-block.caution a:hover,.custom-block.caution a:hover>code{color:var(--vp-c-caution-2)}.custom-block.caution code{background-color:var(--vp-custom-block-caution-code-bg)}.custom-block.details{border-color:var(--vp-custom-block-details-border);color:var(--vp-custom-block-details-text);background-color:var(--vp-custom-block-details-bg)}.custom-block.details a{color:var(--vp-c-brand-1)}.custom-block.details a:hover,.custom-block.details a:hover>code{color:var(--vp-c-brand-2)}.custom-block.details code{background-color:var(--vp-custom-block-details-code-bg)}.custom-block-title{font-weight:600}.custom-block p+p{margin:8px 0}.custom-block.details summary{margin:0 0 8px;font-weight:700;cursor:pointer;-webkit-user-select:none;user-select:none}.custom-block.details summary+p{margin:8px 0}.custom-block a{color:inherit;font-weight:600;text-decoration:underline;text-underline-offset:2px;transition:opacity .25s}.custom-block a:hover{opacity:.75}.custom-block code{font-size:var(--vp-custom-block-code-font-size)}.custom-block.custom-block th,.custom-block.custom-block blockquote>p{font-size:var(--vp-custom-block-font-size);color:inherit}.dark .vp-code span{color:var(--shiki-dark, inherit)}html:not(.dark) .vp-code span{color:var(--shiki-light, inherit)}.vp-code-group{margin-top:16px}.vp-code-group .tabs{position:relative;display:flex;margin-right:-24px;margin-left:-24px;padding:0 12px;background-color:var(--vp-code-tab-bg);overflow-x:auto;overflow-y:hidden;box-shadow:inset 0 -1px var(--vp-code-tab-divider)}@media (min-width: 640px){.vp-code-group .tabs{margin-right:0;margin-left:0;border-radius:8px 8px 0 0}}.vp-code-group .tabs input{position:fixed;opacity:0;pointer-events:none}.vp-code-group .tabs label{position:relative;display:inline-block;border-bottom:1px solid transparent;padding:0 12px;line-height:48px;font-size:14px;font-weight:500;color:var(--vp-code-tab-text-color);white-space:nowrap;cursor:pointer;transition:color .25s}.vp-code-group .tabs label:after{position:absolute;right:8px;bottom:-1px;left:8px;z-index:1;height:2px;border-radius:2px;content:"";background-color:transparent;transition:background-color .25s}.vp-code-group label:hover{color:var(--vp-code-tab-hover-text-color)}.vp-code-group input:checked+label{color:var(--vp-code-tab-active-text-color)}.vp-code-group input:checked+label:after{background-color:var(--vp-code-tab-active-bar-color)}.vp-code-group div[class*=language-],.vp-block{display:none;margin-top:0!important;border-top-left-radius:0!important;border-top-right-radius:0!important}.vp-code-group div[class*=language-].active,.vp-block.active{display:block}.vp-block{padding:20px 24px}.vp-doc h1,.vp-doc h2,.vp-doc h3,.vp-doc h4,.vp-doc h5,.vp-doc h6{position:relative;font-weight:600;outline:none}.vp-doc h1{letter-spacing:-.02em;line-height:40px;font-size:28px}.vp-doc h2{margin:48px 0 16px;border-top:1px solid var(--vp-c-divider);padding-top:24px;letter-spacing:-.02em;line-height:32px;font-size:24px}.vp-doc h3{margin:32px 0 0;letter-spacing:-.01em;line-height:28px;font-size:20px}.vp-doc .header-anchor{position:absolute;top:0;left:0;margin-left:-.87em;font-weight:500;-webkit-user-select:none;user-select:none;opacity:0;text-decoration:none;transition:color .25s,opacity .25s}.vp-doc .header-anchor:before{content:var(--vp-header-anchor-symbol)}.vp-doc h1:hover .header-anchor,.vp-doc h1 .header-anchor:focus,.vp-doc h2:hover .header-anchor,.vp-doc h2 .header-anchor:focus,.vp-doc h3:hover .header-anchor,.vp-doc h3 .header-anchor:focus,.vp-doc h4:hover .header-anchor,.vp-doc h4 .header-anchor:focus,.vp-doc h5:hover .header-anchor,.vp-doc h5 .header-anchor:focus,.vp-doc h6:hover .header-anchor,.vp-doc h6 .header-anchor:focus{opacity:1}@media (min-width: 768px){.vp-doc h1{letter-spacing:-.02em;line-height:40px;font-size:32px}}.vp-doc h2 .header-anchor{top:24px}.vp-doc p,.vp-doc summary{margin:16px 0}.vp-doc p{line-height:28px}.vp-doc blockquote{margin:16px 0;border-left:2px solid var(--vp-c-divider);padding-left:16px;transition:border-color .5s}.vp-doc blockquote>p{margin:0;font-size:16px;color:var(--vp-c-text-2);transition:color .5s}.vp-doc a{font-weight:500;color:var(--vp-c-brand-1);text-decoration:underline;text-underline-offset:2px;transition:color .25s,opacity .25s}.vp-doc a:hover{color:var(--vp-c-brand-2)}.vp-doc strong{font-weight:600}.vp-doc ul,.vp-doc ol{padding-left:1.25rem;margin:16px 0}.vp-doc ul{list-style:disc}.vp-doc ol{list-style:decimal}.vp-doc li+li{margin-top:8px}.vp-doc li>ol,.vp-doc li>ul{margin:8px 0 0}.vp-doc table{display:block;border-collapse:collapse;margin:20px 0;overflow-x:auto}.vp-doc tr{background-color:var(--vp-c-bg);border-top:1px solid var(--vp-c-divider);transition:background-color .5s}.vp-doc tr:nth-child(2n){background-color:var(--vp-c-bg-soft)}.vp-doc th,.vp-doc td{border:1px solid var(--vp-c-divider);padding:8px 16px}.vp-doc th{text-align:left;font-size:14px;font-weight:600;color:var(--vp-c-text-2);background-color:var(--vp-c-bg-soft)}.vp-doc td{font-size:14px}.vp-doc hr{margin:16px 0;border:none;border-top:1px solid var(--vp-c-divider)}.vp-doc .custom-block{margin:16px 0}.vp-doc .custom-block p{margin:8px 0;line-height:24px}.vp-doc .custom-block p:first-child{margin:0}.vp-doc .custom-block div[class*=language-]{margin:8px 0;border-radius:8px}.vp-doc .custom-block div[class*=language-] code{font-weight:400;background-color:transparent}.vp-doc .custom-block .vp-code-group .tabs{margin:0;border-radius:8px 8px 0 0}.vp-doc :not(pre,h1,h2,h3,h4,h5,h6)>code{font-size:var(--vp-code-font-size);color:var(--vp-code-color)}.vp-doc :not(pre)>code{border-radius:4px;padding:3px 6px;background-color:var(--vp-code-bg);transition:color .25s,background-color .5s}.vp-doc a>code{color:var(--vp-code-link-color)}.vp-doc a:hover>code{color:var(--vp-code-link-hover-color)}.vp-doc h1>code,.vp-doc h2>code,.vp-doc h3>code{font-size:.9em}.vp-doc div[class*=language-],.vp-block{position:relative;margin:16px -24px;background-color:var(--vp-code-block-bg);overflow-x:auto;transition:background-color .5s}@media (min-width: 640px){.vp-doc div[class*=language-],.vp-block{border-radius:8px;margin:16px 0}}@media (max-width: 639px){.vp-doc li div[class*=language-]{border-radius:8px 0 0 8px}}.vp-doc div[class*=language-]+div[class*=language-],.vp-doc div[class$=-api]+div[class*=language-],.vp-doc div[class*=language-]+div[class$=-api]>div[class*=language-]{margin-top:-8px}.vp-doc [class*=language-] pre,.vp-doc [class*=language-] code{direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}.vp-doc [class*=language-] pre{position:relative;z-index:1;margin:0;padding:20px 0;background:transparent;overflow-x:auto}.vp-doc [class*=language-] code{display:block;padding:0 24px;width:fit-content;min-width:100%;line-height:var(--vp-code-line-height);font-size:var(--vp-code-font-size);color:var(--vp-code-block-color);transition:color .5s}.vp-doc [class*=language-] code .highlighted{background-color:var(--vp-code-line-highlight-color);transition:background-color .5s;margin:0 -24px;padding:0 24px;width:calc(100% + 48px);display:inline-block}.vp-doc [class*=language-] code .highlighted.error{background-color:var(--vp-code-line-error-color)}.vp-doc [class*=language-] code .highlighted.warning{background-color:var(--vp-code-line-warning-color)}.vp-doc [class*=language-] code .diff{transition:background-color .5s;margin:0 -24px;padding:0 24px;width:calc(100% + 48px);display:inline-block}.vp-doc [class*=language-] code .diff:before{position:absolute;left:10px}.vp-doc [class*=language-] .has-focused-lines .line:not(.has-focus){filter:blur(.095rem);opacity:.4;transition:filter .35s,opacity .35s}.vp-doc [class*=language-] .has-focused-lines .line:not(.has-focus){opacity:.7;transition:filter .35s,opacity .35s}.vp-doc [class*=language-]:hover .has-focused-lines .line:not(.has-focus){filter:blur(0);opacity:1}.vp-doc [class*=language-] code .diff.remove{background-color:var(--vp-code-line-diff-remove-color);opacity:.7}.vp-doc [class*=language-] code .diff.remove:before{content:"-";color:var(--vp-code-line-diff-remove-symbol-color)}.vp-doc [class*=language-] code .diff.add{background-color:var(--vp-code-line-diff-add-color)}.vp-doc [class*=language-] code .diff.add:before{content:"+";color:var(--vp-code-line-diff-add-symbol-color)}.vp-doc div[class*=language-].line-numbers-mode{padding-left:32px}.vp-doc .line-numbers-wrapper{position:absolute;top:0;bottom:0;left:0;z-index:3;border-right:1px solid var(--vp-code-block-divider-color);padding-top:20px;width:32px;text-align:center;font-family:var(--vp-font-family-mono);line-height:var(--vp-code-line-height);font-size:var(--vp-code-font-size);color:var(--vp-code-line-number-color);transition:border-color .5s,color .5s}.vp-doc [class*=language-]>button.copy{direction:ltr;position:absolute;top:12px;right:12px;z-index:3;border:1px solid var(--vp-code-copy-code-border-color);border-radius:4px;width:40px;height:40px;background-color:var(--vp-code-copy-code-bg);opacity:0;cursor:pointer;background-image:var(--vp-icon-copy);background-position:50%;background-size:20px;background-repeat:no-repeat;transition:border-color .25s,background-color .25s,opacity .25s}.vp-doc [class*=language-]:hover>button.copy,.vp-doc [class*=language-]>button.copy:focus{opacity:1}.vp-doc [class*=language-]>button.copy:hover,.vp-doc [class*=language-]>button.copy.copied{border-color:var(--vp-code-copy-code-hover-border-color);background-color:var(--vp-code-copy-code-hover-bg)}.vp-doc [class*=language-]>button.copy.copied,.vp-doc [class*=language-]>button.copy:hover.copied{border-radius:0 4px 4px 0;background-color:var(--vp-code-copy-code-hover-bg);background-image:var(--vp-icon-copied)}.vp-doc [class*=language-]>button.copy.copied:before,.vp-doc [class*=language-]>button.copy:hover.copied:before{position:relative;top:-1px;transform:translate(calc(-100% - 1px));display:flex;justify-content:center;align-items:center;border:1px solid var(--vp-code-copy-code-hover-border-color);border-right:0;border-radius:4px 0 0 4px;padding:0 10px;width:fit-content;height:40px;text-align:center;font-size:12px;font-weight:500;color:var(--vp-code-copy-code-active-text);background-color:var(--vp-code-copy-code-hover-bg);white-space:nowrap;content:var(--vp-code-copy-copied-text-content)}.vp-doc [class*=language-]>span.lang{position:absolute;top:2px;right:8px;z-index:2;font-size:12px;font-weight:500;color:var(--vp-code-lang-color);transition:color .4s,opacity .4s}.vp-doc [class*=language-]:hover>button.copy+span.lang,.vp-doc [class*=language-]>button.copy:focus+span.lang{opacity:0}.vp-doc .VPTeamMembers{margin-top:24px}.vp-doc .VPTeamMembers.small.count-1 .container{margin:0!important;max-width:calc((100% - 24px)/2)!important}.vp-doc .VPTeamMembers.small.count-2 .container,.vp-doc .VPTeamMembers.small.count-3 .container{max-width:100%!important}.vp-doc .VPTeamMembers.medium.count-1 .container{margin:0!important;max-width:calc((100% - 24px)/2)!important}:is(.vp-external-link-icon,.vp-doc a[href*="://"],.vp-doc a[target=_blank]):not(.no-icon):after{display:inline-block;margin-top:-1px;margin-left:4px;width:11px;height:11px;background:currentColor;color:var(--vp-c-text-3);flex-shrink:0;--icon: url("data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' %3E%3Cpath d='M0 0h24v24H0V0z' fill='none' /%3E%3Cpath d='M9 5v2h6.59L4 18.59 5.41 20 17 8.41V15h2V5H9z' /%3E%3C/svg%3E");-webkit-mask-image:var(--icon);mask-image:var(--icon)}.vp-external-link-icon:after{content:""}.external-link-icon-enabled :is(.vp-doc a[href*="://"],.vp-doc a[target=_blank]):after{content:"";color:currentColor}.vp-sponsor{border-radius:16px;overflow:hidden}.vp-sponsor.aside{border-radius:12px}.vp-sponsor-section+.vp-sponsor-section{margin-top:4px}.vp-sponsor-tier{margin:0 0 4px!important;text-align:center;letter-spacing:1px!important;line-height:24px;width:100%;font-weight:600;color:var(--vp-c-text-2);background-color:var(--vp-c-bg-soft)}.vp-sponsor.normal .vp-sponsor-tier{padding:13px 0 11px;font-size:14px}.vp-sponsor.aside .vp-sponsor-tier{padding:9px 0 7px;font-size:12px}.vp-sponsor-grid+.vp-sponsor-tier{margin-top:4px}.vp-sponsor-grid{display:flex;flex-wrap:wrap;gap:4px}.vp-sponsor-grid.xmini .vp-sponsor-grid-link{height:64px}.vp-sponsor-grid.xmini .vp-sponsor-grid-image{max-width:64px;max-height:22px}.vp-sponsor-grid.mini .vp-sponsor-grid-link{height:72px}.vp-sponsor-grid.mini .vp-sponsor-grid-image{max-width:96px;max-height:24px}.vp-sponsor-grid.small .vp-sponsor-grid-link{height:96px}.vp-sponsor-grid.small .vp-sponsor-grid-image{max-width:96px;max-height:24px}.vp-sponsor-grid.medium .vp-sponsor-grid-link{height:112px}.vp-sponsor-grid.medium .vp-sponsor-grid-image{max-width:120px;max-height:36px}.vp-sponsor-grid.big .vp-sponsor-grid-link{height:184px}.vp-sponsor-grid.big .vp-sponsor-grid-image{max-width:192px;max-height:56px}.vp-sponsor-grid[data-vp-grid="2"] .vp-sponsor-grid-item{width:calc((100% - 4px)/2)}.vp-sponsor-grid[data-vp-grid="3"] .vp-sponsor-grid-item{width:calc((100% - 4px * 2) / 3)}.vp-sponsor-grid[data-vp-grid="4"] .vp-sponsor-grid-item{width:calc((100% - 12px)/4)}.vp-sponsor-grid[data-vp-grid="5"] .vp-sponsor-grid-item{width:calc((100% - 16px)/5)}.vp-sponsor-grid[data-vp-grid="6"] .vp-sponsor-grid-item{width:calc((100% - 4px * 5) / 6)}.vp-sponsor-grid-item{flex-shrink:0;width:100%;background-color:var(--vp-c-bg-soft);transition:background-color .25s}.vp-sponsor-grid-item:hover{background-color:var(--vp-c-default-soft)}.vp-sponsor-grid-item:hover .vp-sponsor-grid-image{filter:grayscale(0) invert(0)}.vp-sponsor-grid-item.empty:hover{background-color:var(--vp-c-bg-soft)}.dark .vp-sponsor-grid-item:hover{background-color:var(--vp-c-white)}.dark .vp-sponsor-grid-item.empty:hover{background-color:var(--vp-c-bg-soft)}.vp-sponsor-grid-link{display:flex}.vp-sponsor-grid-box{display:flex;justify-content:center;align-items:center;width:100%}.vp-sponsor-grid-image{max-width:100%;filter:grayscale(1);transition:filter .25s}.dark .vp-sponsor-grid-image{filter:grayscale(1) invert(1)}.VPBadge{display:inline-block;margin-left:2px;border:1px solid transparent;border-radius:12px;padding:0 10px;line-height:22px;font-size:12px;font-weight:500;transform:translateY(-2px)}.VPBadge.small{padding:0 6px;line-height:18px;font-size:10px;transform:translateY(-8px)}.VPDocFooter .VPBadge{display:none}.vp-doc h1>.VPBadge{margin-top:4px;vertical-align:top}.vp-doc h2>.VPBadge{margin-top:3px;padding:0 8px;vertical-align:top}.vp-doc h3>.VPBadge{vertical-align:middle}.vp-doc h4>.VPBadge,.vp-doc h5>.VPBadge,.vp-doc h6>.VPBadge{vertical-align:middle;line-height:18px}.VPBadge.info{border-color:var(--vp-badge-info-border);color:var(--vp-badge-info-text);background-color:var(--vp-badge-info-bg)}.VPBadge.tip{border-color:var(--vp-badge-tip-border);color:var(--vp-badge-tip-text);background-color:var(--vp-badge-tip-bg)}.VPBadge.warning{border-color:var(--vp-badge-warning-border);color:var(--vp-badge-warning-text);background-color:var(--vp-badge-warning-bg)}.VPBadge.danger{border-color:var(--vp-badge-danger-border);color:var(--vp-badge-danger-text);background-color:var(--vp-badge-danger-bg)}.VPBackdrop[data-v-c79a1216]{position:fixed;top:0;right:0;bottom:0;left:0;z-index:var(--vp-z-index-backdrop);background:var(--vp-backdrop-bg-color);transition:opacity .5s}.VPBackdrop.fade-enter-from[data-v-c79a1216],.VPBackdrop.fade-leave-to[data-v-c79a1216]{opacity:0}.VPBackdrop.fade-leave-active[data-v-c79a1216]{transition-duration:.25s}@media (min-width: 1280px){.VPBackdrop[data-v-c79a1216]{display:none}}.NotFound[data-v-d6be1790]{padding:64px 24px 96px;text-align:center}@media (min-width: 768px){.NotFound[data-v-d6be1790]{padding:96px 32px 168px}}.code[data-v-d6be1790]{line-height:64px;font-size:64px;font-weight:600}.title[data-v-d6be1790]{padding-top:12px;letter-spacing:2px;line-height:20px;font-size:20px;font-weight:700}.divider[data-v-d6be1790]{margin:24px auto 18px;width:64px;height:1px;background-color:var(--vp-c-divider)}.quote[data-v-d6be1790]{margin:0 auto;max-width:256px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.action[data-v-d6be1790]{padding-top:20px}.link[data-v-d6be1790]{display:inline-block;border:1px solid var(--vp-c-brand-1);border-radius:16px;padding:3px 16px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:border-color .25s,color .25s}.link[data-v-d6be1790]:hover{border-color:var(--vp-c-brand-2);color:var(--vp-c-brand-2)}.root[data-v-b933a997]{position:relative;z-index:1}.nested[data-v-b933a997]{padding-right:16px;padding-left:16px}.outline-link[data-v-b933a997]{display:block;line-height:32px;font-size:14px;font-weight:400;color:var(--vp-c-text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .5s}.outline-link[data-v-b933a997]:hover,.outline-link.active[data-v-b933a997]{color:var(--vp-c-text-1);transition:color .25s}.outline-link.nested[data-v-b933a997]{padding-left:13px}.VPDocAsideOutline[data-v-a5bbad30]{display:none}.VPDocAsideOutline.has-outline[data-v-a5bbad30]{display:block}.content[data-v-a5bbad30]{position:relative;border-left:1px solid var(--vp-c-divider);padding-left:16px;font-size:13px;font-weight:500}.outline-marker[data-v-a5bbad30]{position:absolute;top:32px;left:-1px;z-index:0;opacity:0;width:2px;border-radius:2px;height:18px;background-color:var(--vp-c-brand-1);transition:top .25s cubic-bezier(0,1,.5,1),background-color .5s,opacity .25s}.outline-title[data-v-a5bbad30]{line-height:32px;font-size:14px;font-weight:600}.VPDocAside[data-v-3f215769]{display:flex;flex-direction:column;flex-grow:1}.spacer[data-v-3f215769]{flex-grow:1}.VPDocAside[data-v-3f215769] .spacer+.VPDocAsideSponsors,.VPDocAside[data-v-3f215769] .spacer+.VPDocAsideCarbonAds{margin-top:24px}.VPDocAside[data-v-3f215769] .VPDocAsideSponsors+.VPDocAsideCarbonAds{margin-top:16px}.VPLastUpdated[data-v-7e05ebdb]{line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}@media (min-width: 640px){.VPLastUpdated[data-v-7e05ebdb]{line-height:32px;font-size:14px;font-weight:500}}.VPDocFooter[data-v-d4a0bba5]{margin-top:64px}.edit-info[data-v-d4a0bba5]{padding-bottom:18px}@media (min-width: 640px){.edit-info[data-v-d4a0bba5]{display:flex;justify-content:space-between;align-items:center;padding-bottom:14px}}.edit-link-button[data-v-d4a0bba5]{display:flex;align-items:center;border:0;line-height:32px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:color .25s}.edit-link-button[data-v-d4a0bba5]:hover{color:var(--vp-c-brand-2)}.edit-link-icon[data-v-d4a0bba5]{margin-right:8px}.prev-next[data-v-d4a0bba5]{border-top:1px solid var(--vp-c-divider);padding-top:24px;display:grid;grid-row-gap:8px}@media (min-width: 640px){.prev-next[data-v-d4a0bba5]{grid-template-columns:repeat(2,1fr);grid-column-gap:16px}}.pager-link[data-v-d4a0bba5]{display:block;border:1px solid var(--vp-c-divider);border-radius:8px;padding:11px 16px 13px;width:100%;height:100%;transition:border-color .25s}.pager-link[data-v-d4a0bba5]:hover{border-color:var(--vp-c-brand-1)}.pager-link.next[data-v-d4a0bba5]{margin-left:auto;text-align:right}.desc[data-v-d4a0bba5]{display:block;line-height:20px;font-size:12px;font-weight:500;color:var(--vp-c-text-2)}.title[data-v-d4a0bba5]{display:block;line-height:20px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:color .25s}.VPDoc[data-v-39a288b8]{padding:32px 24px 96px;width:100%}@media (min-width: 768px){.VPDoc[data-v-39a288b8]{padding:48px 32px 128px}}@media (min-width: 960px){.VPDoc[data-v-39a288b8]{padding:48px 32px 0}.VPDoc:not(.has-sidebar) .container[data-v-39a288b8]{display:flex;justify-content:center;max-width:992px}.VPDoc:not(.has-sidebar) .content[data-v-39a288b8]{max-width:752px}}@media (min-width: 1280px){.VPDoc .container[data-v-39a288b8]{display:flex;justify-content:center}.VPDoc .aside[data-v-39a288b8]{display:block}}@media (min-width: 1440px){.VPDoc:not(.has-sidebar) .content[data-v-39a288b8]{max-width:784px}.VPDoc:not(.has-sidebar) .container[data-v-39a288b8]{max-width:1104px}}.container[data-v-39a288b8]{margin:0 auto;width:100%}.aside[data-v-39a288b8]{position:relative;display:none;order:2;flex-grow:1;padding-left:32px;width:100%;max-width:256px}.left-aside[data-v-39a288b8]{order:1;padding-left:unset;padding-right:32px}.aside-container[data-v-39a288b8]{position:fixed;top:0;padding-top:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + var(--vp-doc-top-height, 0px) + 48px);width:224px;height:100vh;overflow-x:hidden;overflow-y:auto;scrollbar-width:none}.aside-container[data-v-39a288b8]::-webkit-scrollbar{display:none}.aside-curtain[data-v-39a288b8]{position:fixed;bottom:0;z-index:10;width:224px;height:32px;background:linear-gradient(transparent,var(--vp-c-bg) 70%)}.aside-content[data-v-39a288b8]{display:flex;flex-direction:column;min-height:calc(100vh - (var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px));padding-bottom:32px}.content[data-v-39a288b8]{position:relative;margin:0 auto;width:100%}@media (min-width: 960px){.content[data-v-39a288b8]{padding:0 32px 128px}}@media (min-width: 1280px){.content[data-v-39a288b8]{order:1;margin:0;min-width:640px}}.content-container[data-v-39a288b8]{margin:0 auto}.VPDoc.has-aside .content-container[data-v-39a288b8]{max-width:688px}.VPButton[data-v-cad61b99]{display:inline-block;border:1px solid transparent;text-align:center;font-weight:600;white-space:nowrap;transition:color .25s,border-color .25s,background-color .25s}.VPButton[data-v-cad61b99]:active{transition:color .1s,border-color .1s,background-color .1s}.VPButton.medium[data-v-cad61b99]{border-radius:20px;padding:0 20px;line-height:38px;font-size:14px}.VPButton.big[data-v-cad61b99]{border-radius:24px;padding:0 24px;line-height:46px;font-size:16px}.VPButton.brand[data-v-cad61b99]{border-color:var(--vp-button-brand-border);color:var(--vp-button-brand-text);background-color:var(--vp-button-brand-bg)}.VPButton.brand[data-v-cad61b99]:hover{border-color:var(--vp-button-brand-hover-border);color:var(--vp-button-brand-hover-text);background-color:var(--vp-button-brand-hover-bg)}.VPButton.brand[data-v-cad61b99]:active{border-color:var(--vp-button-brand-active-border);color:var(--vp-button-brand-active-text);background-color:var(--vp-button-brand-active-bg)}.VPButton.alt[data-v-cad61b99]{border-color:var(--vp-button-alt-border);color:var(--vp-button-alt-text);background-color:var(--vp-button-alt-bg)}.VPButton.alt[data-v-cad61b99]:hover{border-color:var(--vp-button-alt-hover-border);color:var(--vp-button-alt-hover-text);background-color:var(--vp-button-alt-hover-bg)}.VPButton.alt[data-v-cad61b99]:active{border-color:var(--vp-button-alt-active-border);color:var(--vp-button-alt-active-text);background-color:var(--vp-button-alt-active-bg)}.VPButton.sponsor[data-v-cad61b99]{border-color:var(--vp-button-sponsor-border);color:var(--vp-button-sponsor-text);background-color:var(--vp-button-sponsor-bg)}.VPButton.sponsor[data-v-cad61b99]:hover{border-color:var(--vp-button-sponsor-hover-border);color:var(--vp-button-sponsor-hover-text);background-color:var(--vp-button-sponsor-hover-bg)}.VPButton.sponsor[data-v-cad61b99]:active{border-color:var(--vp-button-sponsor-active-border);color:var(--vp-button-sponsor-active-text);background-color:var(--vp-button-sponsor-active-bg)}html:not(.dark) .VPImage.dark[data-v-8426fc1a]{display:none}.dark .VPImage.light[data-v-8426fc1a]{display:none}.VPHero[data-v-303bb580]{margin-top:calc((var(--vp-nav-height) + var(--vp-layout-top-height, 0px)) * -1);padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px) 24px 48px}@media (min-width: 640px){.VPHero[data-v-303bb580]{padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 48px 64px}}@media (min-width: 960px){.VPHero[data-v-303bb580]{padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 64px 64px}}.container[data-v-303bb580]{display:flex;flex-direction:column;margin:0 auto;max-width:1152px}@media (min-width: 960px){.container[data-v-303bb580]{flex-direction:row}}.main[data-v-303bb580]{position:relative;z-index:10;order:2;flex-grow:1;flex-shrink:0}.VPHero.has-image .container[data-v-303bb580]{text-align:center}@media (min-width: 960px){.VPHero.has-image .container[data-v-303bb580]{text-align:left}}@media (min-width: 960px){.main[data-v-303bb580]{order:1;width:calc((100% / 3) * 2)}.VPHero.has-image .main[data-v-303bb580]{max-width:592px}}.name[data-v-303bb580],.text[data-v-303bb580]{max-width:392px;letter-spacing:-.4px;line-height:40px;font-size:32px;font-weight:700;white-space:pre-wrap}.VPHero.has-image .name[data-v-303bb580],.VPHero.has-image .text[data-v-303bb580]{margin:0 auto}.name[data-v-303bb580]{color:var(--vp-home-hero-name-color)}.clip[data-v-303bb580]{background:var(--vp-home-hero-name-background);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:var(--vp-home-hero-name-color)}@media (min-width: 640px){.name[data-v-303bb580],.text[data-v-303bb580]{max-width:576px;line-height:56px;font-size:48px}}@media (min-width: 960px){.name[data-v-303bb580],.text[data-v-303bb580]{line-height:64px;font-size:56px}.VPHero.has-image .name[data-v-303bb580],.VPHero.has-image .text[data-v-303bb580]{margin:0}}.tagline[data-v-303bb580]{padding-top:8px;max-width:392px;line-height:28px;font-size:18px;font-weight:500;white-space:pre-wrap;color:var(--vp-c-text-2)}.VPHero.has-image .tagline[data-v-303bb580]{margin:0 auto}@media (min-width: 640px){.tagline[data-v-303bb580]{padding-top:12px;max-width:576px;line-height:32px;font-size:20px}}@media (min-width: 960px){.tagline[data-v-303bb580]{line-height:36px;font-size:24px}.VPHero.has-image .tagline[data-v-303bb580]{margin:0}}.actions[data-v-303bb580]{display:flex;flex-wrap:wrap;margin:-6px;padding-top:24px}.VPHero.has-image .actions[data-v-303bb580]{justify-content:center}@media (min-width: 640px){.actions[data-v-303bb580]{padding-top:32px}}@media (min-width: 960px){.VPHero.has-image .actions[data-v-303bb580]{justify-content:flex-start}}.action[data-v-303bb580]{flex-shrink:0;padding:6px}.image[data-v-303bb580]{order:1;margin:-76px -24px -48px}@media (min-width: 640px){.image[data-v-303bb580]{margin:-108px -24px -48px}}@media (min-width: 960px){.image[data-v-303bb580]{flex-grow:1;order:2;margin:0;min-height:100%}}.image-container[data-v-303bb580]{position:relative;margin:0 auto;width:320px;height:320px}@media (min-width: 640px){.image-container[data-v-303bb580]{width:392px;height:392px}}@media (min-width: 960px){.image-container[data-v-303bb580]{display:flex;justify-content:center;align-items:center;width:100%;height:100%;transform:translate(-32px,-32px)}}.image-bg[data-v-303bb580]{position:absolute;top:50%;left:50%;border-radius:50%;width:192px;height:192px;background-image:var(--vp-home-hero-image-background-image);filter:var(--vp-home-hero-image-filter);transform:translate(-50%,-50%)}@media (min-width: 640px){.image-bg[data-v-303bb580]{width:256px;height:256px}}@media (min-width: 960px){.image-bg[data-v-303bb580]{width:320px;height:320px}}[data-v-303bb580] .image-src{position:absolute;top:50%;left:50%;max-width:192px;max-height:192px;transform:translate(-50%,-50%)}@media (min-width: 640px){[data-v-303bb580] .image-src{max-width:256px;max-height:256px}}@media (min-width: 960px){[data-v-303bb580] .image-src{max-width:320px;max-height:320px}}.VPFeature[data-v-a3976bdc]{display:block;border:1px solid var(--vp-c-bg-soft);border-radius:12px;height:100%;background-color:var(--vp-c-bg-soft);transition:border-color .25s,background-color .25s}.VPFeature.link[data-v-a3976bdc]:hover{border-color:var(--vp-c-brand-1)}.box[data-v-a3976bdc]{display:flex;flex-direction:column;padding:24px;height:100%}.box[data-v-a3976bdc]>.VPImage{margin-bottom:20px}.icon[data-v-a3976bdc]{display:flex;justify-content:center;align-items:center;margin-bottom:20px;border-radius:6px;background-color:var(--vp-c-default-soft);width:48px;height:48px;font-size:24px;transition:background-color .25s}.title[data-v-a3976bdc]{line-height:24px;font-size:16px;font-weight:600}.details[data-v-a3976bdc]{flex-grow:1;padding-top:8px;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.link-text[data-v-a3976bdc]{padding-top:8px}.link-text-value[data-v-a3976bdc]{display:flex;align-items:center;font-size:14px;font-weight:500;color:var(--vp-c-brand-1)}.link-text-icon[data-v-a3976bdc]{margin-left:6px}.VPFeatures[data-v-a6181336]{position:relative;padding:0 24px}@media (min-width: 640px){.VPFeatures[data-v-a6181336]{padding:0 48px}}@media (min-width: 960px){.VPFeatures[data-v-a6181336]{padding:0 64px}}.container[data-v-a6181336]{margin:0 auto;max-width:1152px}.items[data-v-a6181336]{display:flex;flex-wrap:wrap;margin:-8px}.item[data-v-a6181336]{padding:8px;width:100%}@media (min-width: 640px){.item.grid-2[data-v-a6181336],.item.grid-4[data-v-a6181336],.item.grid-6[data-v-a6181336]{width:50%}}@media (min-width: 768px){.item.grid-2[data-v-a6181336],.item.grid-4[data-v-a6181336]{width:50%}.item.grid-3[data-v-a6181336],.item.grid-6[data-v-a6181336]{width:calc(100% / 3)}}@media (min-width: 960px){.item.grid-4[data-v-a6181336]{width:25%}}.container[data-v-8e2d4988]{margin:auto;width:100%;max-width:1280px;padding:0 24px}@media (min-width: 640px){.container[data-v-8e2d4988]{padding:0 48px}}@media (min-width: 960px){.container[data-v-8e2d4988]{width:100%;padding:0 64px}}.vp-doc[data-v-8e2d4988] .VPHomeSponsors,.vp-doc[data-v-8e2d4988] .VPTeamPage{margin-left:var(--vp-offset, calc(50% - 50vw) );margin-right:var(--vp-offset, calc(50% - 50vw) )}.vp-doc[data-v-8e2d4988] .VPHomeSponsors h2{border-top:none;letter-spacing:normal}.vp-doc[data-v-8e2d4988] .VPHomeSponsors a,.vp-doc[data-v-8e2d4988] .VPTeamPage a{text-decoration:none}.VPHome[data-v-686f80a6]{margin-bottom:96px}@media (min-width: 768px){.VPHome[data-v-686f80a6]{margin-bottom:128px}}.VPContent[data-v-1428d186]{flex-grow:1;flex-shrink:0;margin:var(--vp-layout-top-height, 0px) auto 0;width:100%}.VPContent.is-home[data-v-1428d186]{width:100%;max-width:100%}.VPContent.has-sidebar[data-v-1428d186]{margin:0}@media (min-width: 960px){.VPContent[data-v-1428d186]{padding-top:var(--vp-nav-height)}.VPContent.has-sidebar[data-v-1428d186]{margin:var(--vp-layout-top-height, 0px) 0 0;padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPContent.has-sidebar[data-v-1428d186]{padding-right:calc((100vw - var(--vp-layout-max-width)) / 2);padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.VPFooter[data-v-e315a0ad]{position:relative;z-index:var(--vp-z-index-footer);border-top:1px solid var(--vp-c-gutter);padding:32px 24px;background-color:var(--vp-c-bg)}.VPFooter.has-sidebar[data-v-e315a0ad]{display:none}.VPFooter[data-v-e315a0ad] a{text-decoration-line:underline;text-underline-offset:2px;transition:color .25s}.VPFooter[data-v-e315a0ad] a:hover{color:var(--vp-c-text-1)}@media (min-width: 768px){.VPFooter[data-v-e315a0ad]{padding:32px}}.container[data-v-e315a0ad]{margin:0 auto;max-width:var(--vp-layout-max-width);text-align:center}.message[data-v-e315a0ad],.copyright[data-v-e315a0ad]{line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.VPLocalNavOutlineDropdown[data-v-17a5e62e]{padding:12px 20px 11px}@media (min-width: 960px){.VPLocalNavOutlineDropdown[data-v-17a5e62e]{padding:12px 36px 11px}}.VPLocalNavOutlineDropdown button[data-v-17a5e62e]{display:block;font-size:12px;font-weight:500;line-height:24px;color:var(--vp-c-text-2);transition:color .5s;position:relative}.VPLocalNavOutlineDropdown button[data-v-17a5e62e]:hover{color:var(--vp-c-text-1);transition:color .25s}.VPLocalNavOutlineDropdown button.open[data-v-17a5e62e]{color:var(--vp-c-text-1)}.icon[data-v-17a5e62e]{display:inline-block;vertical-align:middle;margin-left:2px;font-size:14px;transform:rotate(0);transition:transform .25s}@media (min-width: 960px){.VPLocalNavOutlineDropdown button[data-v-17a5e62e]{font-size:14px}.icon[data-v-17a5e62e]{font-size:16px}}.open>.icon[data-v-17a5e62e]{transform:rotate(90deg)}.items[data-v-17a5e62e]{position:absolute;top:40px;right:16px;left:16px;display:grid;gap:1px;border:1px solid var(--vp-c-border);border-radius:8px;background-color:var(--vp-c-gutter);max-height:calc(var(--vp-vh, 100vh) - 86px);overflow:hidden auto;box-shadow:var(--vp-shadow-3)}@media (min-width: 960px){.items[data-v-17a5e62e]{right:auto;left:calc(var(--vp-sidebar-width) + 32px);width:320px}}.header[data-v-17a5e62e]{background-color:var(--vp-c-bg-soft)}.top-link[data-v-17a5e62e]{display:block;padding:0 16px;line-height:48px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1)}.outline[data-v-17a5e62e]{padding:8px 0;background-color:var(--vp-c-bg-soft)}.flyout-enter-active[data-v-17a5e62e]{transition:all .2s ease-out}.flyout-leave-active[data-v-17a5e62e]{transition:all .15s ease-in}.flyout-enter-from[data-v-17a5e62e],.flyout-leave-to[data-v-17a5e62e]{opacity:0;transform:translateY(-16px)}.VPLocalNav[data-v-a6f0e41e]{position:sticky;top:0;left:0;z-index:var(--vp-z-index-local-nav);border-bottom:1px solid var(--vp-c-gutter);padding-top:var(--vp-layout-top-height, 0px);width:100%;background-color:var(--vp-local-nav-bg-color)}.VPLocalNav.fixed[data-v-a6f0e41e]{position:fixed}@media (min-width: 960px){.VPLocalNav[data-v-a6f0e41e]{top:var(--vp-nav-height)}.VPLocalNav.has-sidebar[data-v-a6f0e41e]{padding-left:var(--vp-sidebar-width)}.VPLocalNav.empty[data-v-a6f0e41e]{display:none}}@media (min-width: 1280px){.VPLocalNav[data-v-a6f0e41e]{display:none}}@media (min-width: 1440px){.VPLocalNav.has-sidebar[data-v-a6f0e41e]{padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.container[data-v-a6f0e41e]{display:flex;justify-content:space-between;align-items:center}.menu[data-v-a6f0e41e]{display:flex;align-items:center;padding:12px 24px 11px;line-height:24px;font-size:12px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.menu[data-v-a6f0e41e]:hover{color:var(--vp-c-text-1);transition:color .25s}@media (min-width: 768px){.menu[data-v-a6f0e41e]{padding:0 32px}}@media (min-width: 960px){.menu[data-v-a6f0e41e]{display:none}}.menu-icon[data-v-a6f0e41e]{margin-right:8px;font-size:14px}.VPOutlineDropdown[data-v-a6f0e41e]{padding:12px 24px 11px}@media (min-width: 768px){.VPOutlineDropdown[data-v-a6f0e41e]{padding:12px 32px 11px}}.VPSwitch[data-v-1d5665e3]{position:relative;border-radius:11px;display:block;width:40px;height:22px;flex-shrink:0;border:1px solid var(--vp-input-border-color);background-color:var(--vp-input-switch-bg-color);transition:border-color .25s!important}.VPSwitch[data-v-1d5665e3]:hover{border-color:var(--vp-c-brand-1)}.check[data-v-1d5665e3]{position:absolute;top:1px;left:1px;width:18px;height:18px;border-radius:50%;background-color:var(--vp-c-neutral-inverse);box-shadow:var(--vp-shadow-1);transition:transform .25s!important}.icon[data-v-1d5665e3]{position:relative;display:block;width:18px;height:18px;border-radius:50%;overflow:hidden}.icon[data-v-1d5665e3] [class^=vpi-]{position:absolute;top:3px;left:3px;width:12px;height:12px;color:var(--vp-c-text-2)}.dark .icon[data-v-1d5665e3] [class^=vpi-]{color:var(--vp-c-text-1);transition:opacity .25s!important}.sun[data-v-d1f28634]{opacity:1}.moon[data-v-d1f28634],.dark .sun[data-v-d1f28634]{opacity:0}.dark .moon[data-v-d1f28634]{opacity:1}.dark .VPSwitchAppearance[data-v-d1f28634] .check{transform:translate(18px)}.VPNavBarAppearance[data-v-e6aabb21]{display:none}@media (min-width: 1280px){.VPNavBarAppearance[data-v-e6aabb21]{display:flex;align-items:center}}.VPMenuGroup+.VPMenuLink[data-v-43f1e123]{margin:12px -12px 0;border-top:1px solid var(--vp-c-divider);padding:12px 12px 0}.link[data-v-43f1e123]{display:block;border-radius:6px;padding:0 12px;line-height:32px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);white-space:nowrap;transition:background-color .25s,color .25s}.link[data-v-43f1e123]:hover{color:var(--vp-c-brand-1);background-color:var(--vp-c-default-soft)}.link.active[data-v-43f1e123]{color:var(--vp-c-brand-1)}.VPMenuGroup[data-v-69e747b5]{margin:12px -12px 0;border-top:1px solid var(--vp-c-divider);padding:12px 12px 0}.VPMenuGroup[data-v-69e747b5]:first-child{margin-top:0;border-top:0;padding-top:0}.VPMenuGroup+.VPMenuGroup[data-v-69e747b5]{margin-top:12px;border-top:1px solid var(--vp-c-divider)}.title[data-v-69e747b5]{padding:0 12px;line-height:32px;font-size:14px;font-weight:600;color:var(--vp-c-text-2);white-space:nowrap;transition:color .25s}.VPMenu[data-v-e7ea1737]{border-radius:12px;padding:12px;min-width:128px;border:1px solid var(--vp-c-divider);background-color:var(--vp-c-bg-elv);box-shadow:var(--vp-shadow-3);transition:background-color .5s;max-height:calc(100vh - var(--vp-nav-height));overflow-y:auto}.VPMenu[data-v-e7ea1737] .group{margin:0 -12px;padding:0 12px 12px}.VPMenu[data-v-e7ea1737] .group+.group{border-top:1px solid var(--vp-c-divider);padding:11px 12px 12px}.VPMenu[data-v-e7ea1737] .group:last-child{padding-bottom:0}.VPMenu[data-v-e7ea1737] .group+.item{border-top:1px solid var(--vp-c-divider);padding:11px 16px 0}.VPMenu[data-v-e7ea1737] .item{padding:0 16px;white-space:nowrap}.VPMenu[data-v-e7ea1737] .label{flex-grow:1;line-height:28px;font-size:12px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.VPMenu[data-v-e7ea1737] .action{padding-left:24px}.VPFlyout[data-v-b6c34ac9]{position:relative}.VPFlyout[data-v-b6c34ac9]:hover{color:var(--vp-c-brand-1);transition:color .25s}.VPFlyout:hover .text[data-v-b6c34ac9]{color:var(--vp-c-text-2)}.VPFlyout:hover .icon[data-v-b6c34ac9]{fill:var(--vp-c-text-2)}.VPFlyout.active .text[data-v-b6c34ac9]{color:var(--vp-c-brand-1)}.VPFlyout.active:hover .text[data-v-b6c34ac9]{color:var(--vp-c-brand-2)}.VPFlyout:hover .menu[data-v-b6c34ac9],.button[aria-expanded=true]+.menu[data-v-b6c34ac9]{opacity:1;visibility:visible;transform:translateY(0)}.button[aria-expanded=false]+.menu[data-v-b6c34ac9]{opacity:0;visibility:hidden;transform:translateY(0)}.button[data-v-b6c34ac9]{display:flex;align-items:center;padding:0 12px;height:var(--vp-nav-height);color:var(--vp-c-text-1);transition:color .5s}.text[data-v-b6c34ac9]{display:flex;align-items:center;line-height:var(--vp-nav-height);font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.option-icon[data-v-b6c34ac9]{margin-right:0;font-size:16px}.text-icon[data-v-b6c34ac9]{margin-left:4px;font-size:14px}.icon[data-v-b6c34ac9]{font-size:20px;transition:fill .25s}.menu[data-v-b6c34ac9]{position:absolute;top:calc(var(--vp-nav-height) / 2 + 20px);right:0;opacity:0;visibility:hidden;transition:opacity .25s,visibility .25s,transform .25s}.VPSocialLink[data-v-eee4e7cb]{display:flex;justify-content:center;align-items:center;width:36px;height:36px;color:var(--vp-c-text-2);transition:color .5s}.VPSocialLink[data-v-eee4e7cb]:hover{color:var(--vp-c-text-1);transition:color .25s}.VPSocialLink[data-v-eee4e7cb]>svg,.VPSocialLink[data-v-eee4e7cb]>[class^=vpi-social-]{width:20px;height:20px;fill:currentColor}.VPSocialLinks[data-v-7bc22406]{display:flex;justify-content:center}.VPNavBarExtra[data-v-d0bd9dde]{display:none;margin-right:-12px}@media (min-width: 768px){.VPNavBarExtra[data-v-d0bd9dde]{display:block}}@media (min-width: 1280px){.VPNavBarExtra[data-v-d0bd9dde]{display:none}}.trans-title[data-v-d0bd9dde]{padding:0 24px 0 12px;line-height:32px;font-size:14px;font-weight:700;color:var(--vp-c-text-1)}.item.appearance[data-v-d0bd9dde],.item.social-links[data-v-d0bd9dde]{display:flex;align-items:center;padding:0 12px}.item.appearance[data-v-d0bd9dde]{min-width:176px}.appearance-action[data-v-d0bd9dde]{margin-right:-2px}.social-links-list[data-v-d0bd9dde]{margin:-4px -8px}.VPNavBarHamburger[data-v-e5dd9c1c]{display:flex;justify-content:center;align-items:center;width:48px;height:var(--vp-nav-height)}@media (min-width: 768px){.VPNavBarHamburger[data-v-e5dd9c1c]{display:none}}.container[data-v-e5dd9c1c]{position:relative;width:16px;height:14px;overflow:hidden}.VPNavBarHamburger:hover .top[data-v-e5dd9c1c]{top:0;left:0;transform:translate(4px)}.VPNavBarHamburger:hover .middle[data-v-e5dd9c1c]{top:6px;left:0;transform:translate(0)}.VPNavBarHamburger:hover .bottom[data-v-e5dd9c1c]{top:12px;left:0;transform:translate(8px)}.VPNavBarHamburger.active .top[data-v-e5dd9c1c]{top:6px;transform:translate(0) rotate(225deg)}.VPNavBarHamburger.active .middle[data-v-e5dd9c1c]{top:6px;transform:translate(16px)}.VPNavBarHamburger.active .bottom[data-v-e5dd9c1c]{top:6px;transform:translate(0) rotate(135deg)}.VPNavBarHamburger.active:hover .top[data-v-e5dd9c1c],.VPNavBarHamburger.active:hover .middle[data-v-e5dd9c1c],.VPNavBarHamburger.active:hover .bottom[data-v-e5dd9c1c]{background-color:var(--vp-c-text-2);transition:top .25s,background-color .25s,transform .25s}.top[data-v-e5dd9c1c],.middle[data-v-e5dd9c1c],.bottom[data-v-e5dd9c1c]{position:absolute;width:16px;height:2px;background-color:var(--vp-c-text-1);transition:top .25s,background-color .5s,transform .25s}.top[data-v-e5dd9c1c]{top:0;left:0;transform:translate(0)}.middle[data-v-e5dd9c1c]{top:6px;left:0;transform:translate(8px)}.bottom[data-v-e5dd9c1c]{top:12px;left:0;transform:translate(4px)}.VPNavBarMenuLink[data-v-9c663999]{display:flex;align-items:center;padding:0 12px;line-height:var(--vp-nav-height);font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.VPNavBarMenuLink.active[data-v-9c663999],.VPNavBarMenuLink[data-v-9c663999]:hover{color:var(--vp-c-brand-1)}.VPNavBarMenu[data-v-7f418b0f]{display:none}@media (min-width: 768px){.VPNavBarMenu[data-v-7f418b0f]{display:flex}}/*! @docsearch/css 3.6.0 | MIT License | © Algolia, Inc. and contributors | https://docsearch.algolia.com */:root{--docsearch-primary-color:#5468ff;--docsearch-text-color:#1c1e21;--docsearch-spacing:12px;--docsearch-icon-stroke-width:1.4;--docsearch-highlight-color:var(--docsearch-primary-color);--docsearch-muted-color:#969faf;--docsearch-container-background:rgba(101,108,133,.8);--docsearch-logo-color:#5468ff;--docsearch-modal-width:560px;--docsearch-modal-height:600px;--docsearch-modal-background:#f5f6f7;--docsearch-modal-shadow:inset 1px 1px 0 0 hsla(0,0%,100%,.5),0 3px 8px 0 #555a64;--docsearch-searchbox-height:56px;--docsearch-searchbox-background:#ebedf0;--docsearch-searchbox-focus-background:#fff;--docsearch-searchbox-shadow:inset 0 0 0 2px var(--docsearch-primary-color);--docsearch-hit-height:56px;--docsearch-hit-color:#444950;--docsearch-hit-active-color:#fff;--docsearch-hit-background:#fff;--docsearch-hit-shadow:0 1px 3px 0 #d4d9e1;--docsearch-key-gradient:linear-gradient(-225deg,#d5dbe4,#f8f8f8);--docsearch-key-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 2px 1px rgba(30,35,90,.4);--docsearch-key-pressed-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 1px 0 rgba(30,35,90,.4);--docsearch-footer-height:44px;--docsearch-footer-background:#fff;--docsearch-footer-shadow:0 -1px 0 0 #e0e3e8,0 -3px 6px 0 rgba(69,98,155,.12)}html[data-theme=dark]{--docsearch-text-color:#f5f6f7;--docsearch-container-background:rgba(9,10,17,.8);--docsearch-modal-background:#15172a;--docsearch-modal-shadow:inset 1px 1px 0 0 #2c2e40,0 3px 8px 0 #000309;--docsearch-searchbox-background:#090a11;--docsearch-searchbox-focus-background:#000;--docsearch-hit-color:#bec3c9;--docsearch-hit-shadow:none;--docsearch-hit-background:#090a11;--docsearch-key-gradient:linear-gradient(-26.5deg,#565872,#31355b);--docsearch-key-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 2px 2px 0 rgba(3,4,9,.3);--docsearch-key-pressed-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 1px 1px 0 rgba(3,4,9,.30196078431372547);--docsearch-footer-background:#1e2136;--docsearch-footer-shadow:inset 0 1px 0 0 rgba(73,76,106,.5),0 -4px 8px 0 rgba(0,0,0,.2);--docsearch-logo-color:#fff;--docsearch-muted-color:#7f8497}.DocSearch-Button{align-items:center;background:var(--docsearch-searchbox-background);border:0;border-radius:40px;color:var(--docsearch-muted-color);cursor:pointer;display:flex;font-weight:500;height:36px;justify-content:space-between;margin:0 0 0 16px;padding:0 8px;-webkit-user-select:none;user-select:none}.DocSearch-Button:active,.DocSearch-Button:focus,.DocSearch-Button:hover{background:var(--docsearch-searchbox-focus-background);box-shadow:var(--docsearch-searchbox-shadow);color:var(--docsearch-text-color);outline:none}.DocSearch-Button-Container{align-items:center;display:flex}.DocSearch-Search-Icon{stroke-width:1.6}.DocSearch-Button .DocSearch-Search-Icon{color:var(--docsearch-text-color)}.DocSearch-Button-Placeholder{font-size:1rem;padding:0 12px 0 6px}.DocSearch-Button-Keys{display:flex;min-width:calc(40px + .8em)}.DocSearch-Button-Key{align-items:center;background:var(--docsearch-key-gradient);border-radius:3px;box-shadow:var(--docsearch-key-shadow);color:var(--docsearch-muted-color);display:flex;height:18px;justify-content:center;margin-right:.4em;position:relative;padding:0 0 2px;border:0;top:-1px;width:20px}.DocSearch-Button-Key--pressed{transform:translate3d(0,1px,0);box-shadow:var(--docsearch-key-pressed-shadow)}@media (max-width:768px){.DocSearch-Button-Keys,.DocSearch-Button-Placeholder{display:none}}.DocSearch--active{overflow:hidden!important}.DocSearch-Container,.DocSearch-Container *{box-sizing:border-box}.DocSearch-Container{background-color:var(--docsearch-container-background);height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:200}.DocSearch-Container a{text-decoration:none}.DocSearch-Link{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;font:inherit;margin:0;padding:0}.DocSearch-Modal{background:var(--docsearch-modal-background);border-radius:6px;box-shadow:var(--docsearch-modal-shadow);flex-direction:column;margin:60px auto auto;max-width:var(--docsearch-modal-width);position:relative}.DocSearch-SearchBar{display:flex;padding:var(--docsearch-spacing) var(--docsearch-spacing) 0}.DocSearch-Form{align-items:center;background:var(--docsearch-searchbox-focus-background);border-radius:4px;box-shadow:var(--docsearch-searchbox-shadow);display:flex;height:var(--docsearch-searchbox-height);margin:0;padding:0 var(--docsearch-spacing);position:relative;width:100%}.DocSearch-Input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border:0;color:var(--docsearch-text-color);flex:1;font:inherit;font-size:1.2em;height:100%;outline:none;padding:0 0 0 8px;width:80%}.DocSearch-Input::placeholder{color:var(--docsearch-muted-color);opacity:1}.DocSearch-Input::-webkit-search-cancel-button,.DocSearch-Input::-webkit-search-decoration,.DocSearch-Input::-webkit-search-results-button,.DocSearch-Input::-webkit-search-results-decoration{display:none}.DocSearch-LoadingIndicator,.DocSearch-MagnifierLabel,.DocSearch-Reset{margin:0;padding:0}.DocSearch-MagnifierLabel,.DocSearch-Reset{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}.DocSearch-Container--Stalled .DocSearch-MagnifierLabel,.DocSearch-LoadingIndicator{display:none}.DocSearch-Container--Stalled .DocSearch-LoadingIndicator{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Reset{animation:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;right:0;stroke-width:var(--docsearch-icon-stroke-width)}}.DocSearch-Reset{animation:fade-in .1s ease-in forwards;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;padding:2px;right:0;stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Reset[hidden]{display:none}.DocSearch-Reset:hover{color:var(--docsearch-highlight-color)}.DocSearch-LoadingIndicator svg,.DocSearch-MagnifierLabel svg{height:24px;width:24px}.DocSearch-Cancel{display:none}.DocSearch-Dropdown{max-height:calc(var(--docsearch-modal-height) - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height));min-height:var(--docsearch-spacing);overflow-y:auto;overflow-y:overlay;padding:0 var(--docsearch-spacing);scrollbar-color:var(--docsearch-muted-color) var(--docsearch-modal-background);scrollbar-width:thin}.DocSearch-Dropdown::-webkit-scrollbar{width:12px}.DocSearch-Dropdown::-webkit-scrollbar-track{background:transparent}.DocSearch-Dropdown::-webkit-scrollbar-thumb{background-color:var(--docsearch-muted-color);border:3px solid var(--docsearch-modal-background);border-radius:20px}.DocSearch-Dropdown ul{list-style:none;margin:0;padding:0}.DocSearch-Label{font-size:.75em;line-height:1.6em}.DocSearch-Help,.DocSearch-Label{color:var(--docsearch-muted-color)}.DocSearch-Help{font-size:.9em;margin:0;-webkit-user-select:none;user-select:none}.DocSearch-Title{font-size:1.2em}.DocSearch-Logo a{display:flex}.DocSearch-Logo svg{color:var(--docsearch-logo-color);margin-left:8px}.DocSearch-Hits:last-of-type{margin-bottom:24px}.DocSearch-Hits mark{background:none;color:var(--docsearch-highlight-color)}.DocSearch-HitsFooter{color:var(--docsearch-muted-color);display:flex;font-size:.85em;justify-content:center;margin-bottom:var(--docsearch-spacing);padding:var(--docsearch-spacing)}.DocSearch-HitsFooter a{border-bottom:1px solid;color:inherit}.DocSearch-Hit{border-radius:4px;display:flex;padding-bottom:4px;position:relative}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--deleting{transition:none}}.DocSearch-Hit--deleting{opacity:0;transition:all .25s linear}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--favoriting{transition:none}}.DocSearch-Hit--favoriting{transform:scale(0);transform-origin:top center;transition:all .25s linear;transition-delay:.25s}.DocSearch-Hit a{background:var(--docsearch-hit-background);border-radius:4px;box-shadow:var(--docsearch-hit-shadow);display:block;padding-left:var(--docsearch-spacing);width:100%}.DocSearch-Hit-source{background:var(--docsearch-modal-background);color:var(--docsearch-highlight-color);font-size:.85em;font-weight:600;line-height:32px;margin:0 -4px;padding:8px 4px 0;position:sticky;top:0;z-index:10}.DocSearch-Hit-Tree{color:var(--docsearch-muted-color);height:var(--docsearch-hit-height);opacity:.5;stroke-width:var(--docsearch-icon-stroke-width);width:24px}.DocSearch-Hit[aria-selected=true] a{background-color:var(--docsearch-highlight-color)}.DocSearch-Hit[aria-selected=true] mark{text-decoration:underline}.DocSearch-Hit-Container{align-items:center;color:var(--docsearch-hit-color);display:flex;flex-direction:row;height:var(--docsearch-hit-height);padding:0 var(--docsearch-spacing) 0 0}.DocSearch-Hit-icon{height:20px;width:20px}.DocSearch-Hit-action,.DocSearch-Hit-icon{color:var(--docsearch-muted-color);stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Hit-action{align-items:center;display:flex;height:22px;width:22px}.DocSearch-Hit-action svg{display:block;height:18px;width:18px}.DocSearch-Hit-action+.DocSearch-Hit-action{margin-left:6px}.DocSearch-Hit-action-button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:inherit;cursor:pointer;padding:2px}svg.DocSearch-Hit-Select-Icon{display:none}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Select-Icon{display:block}.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:#0003;transition:background-color .1s ease-in}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{transition:none}}.DocSearch-Hit-action-button:focus path,.DocSearch-Hit-action-button:hover path{fill:#fff}.DocSearch-Hit-content-wrapper{display:flex;flex:1 1 auto;flex-direction:column;font-weight:500;justify-content:center;line-height:1.2em;margin:0 8px;overflow-x:hidden;position:relative;text-overflow:ellipsis;white-space:nowrap;width:80%}.DocSearch-Hit-title{font-size:.9em}.DocSearch-Hit-path{color:var(--docsearch-muted-color);font-size:.75em}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-action,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-icon,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-path,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-text,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-title,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Tree,.DocSearch-Hit[aria-selected=true] mark{color:var(--docsearch-hit-active-color)!important}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:#0003;transition:none}}.DocSearch-ErrorScreen,.DocSearch-NoResults,.DocSearch-StartScreen{font-size:.9em;margin:0 auto;padding:36px 0;text-align:center;width:80%}.DocSearch-Screen-Icon{color:var(--docsearch-muted-color);padding-bottom:12px}.DocSearch-NoResults-Prefill-List{display:inline-block;padding-bottom:24px;text-align:left}.DocSearch-NoResults-Prefill-List ul{display:inline-block;padding:8px 0 0}.DocSearch-NoResults-Prefill-List li{list-style-position:inside;list-style-type:"» "}.DocSearch-Prefill{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:1em;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;font-size:1em;font-weight:700;padding:0}.DocSearch-Prefill:focus,.DocSearch-Prefill:hover{outline:none;text-decoration:underline}.DocSearch-Footer{align-items:center;background:var(--docsearch-footer-background);border-radius:0 0 8px 8px;box-shadow:var(--docsearch-footer-shadow);display:flex;flex-direction:row-reverse;flex-shrink:0;height:var(--docsearch-footer-height);justify-content:space-between;padding:0 var(--docsearch-spacing);position:relative;-webkit-user-select:none;user-select:none;width:100%;z-index:300}.DocSearch-Commands{color:var(--docsearch-muted-color);display:flex;list-style:none;margin:0;padding:0}.DocSearch-Commands li{align-items:center;display:flex}.DocSearch-Commands li:not(:last-of-type){margin-right:.8em}.DocSearch-Commands-Key{align-items:center;background:var(--docsearch-key-gradient);border-radius:2px;box-shadow:var(--docsearch-key-shadow);display:flex;height:18px;justify-content:center;margin-right:.4em;padding:0 0 1px;color:var(--docsearch-muted-color);border:0;width:20px}.DocSearch-VisuallyHiddenForAccessibility{clip:rect(0 0 0 0);clip-path:inset(50%);height:1px;overflow:hidden;position:absolute;white-space:nowrap;width:1px}@media (max-width:768px){:root{--docsearch-spacing:10px;--docsearch-footer-height:40px}.DocSearch-Dropdown{height:100%}.DocSearch-Container{height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);position:absolute}.DocSearch-Footer{border-radius:0;bottom:0;position:absolute}.DocSearch-Hit-content-wrapper{display:flex;position:relative;width:80%}.DocSearch-Modal{border-radius:0;box-shadow:none;height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);margin:0;max-width:100%;width:100%}.DocSearch-Dropdown{max-height:calc(var(--docsearch-vh, 1vh)*100 - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height))}.DocSearch-Cancel{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;flex:none;font:inherit;font-size:1em;font-weight:500;margin-left:var(--docsearch-spacing);outline:none;overflow:hidden;padding:0;-webkit-user-select:none;user-select:none;white-space:nowrap}.DocSearch-Commands,.DocSearch-Hit-Tree{display:none}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}[class*=DocSearch]{--docsearch-primary-color: var(--vp-c-brand-1);--docsearch-highlight-color: var(--docsearch-primary-color);--docsearch-text-color: var(--vp-c-text-1);--docsearch-muted-color: var(--vp-c-text-2);--docsearch-searchbox-shadow: none;--docsearch-searchbox-background: transparent;--docsearch-searchbox-focus-background: transparent;--docsearch-key-gradient: transparent;--docsearch-key-shadow: none;--docsearch-modal-background: var(--vp-c-bg-soft);--docsearch-footer-background: var(--vp-c-bg)}.dark [class*=DocSearch]{--docsearch-modal-shadow: none;--docsearch-footer-shadow: none;--docsearch-logo-color: var(--vp-c-text-2);--docsearch-hit-background: var(--vp-c-default-soft);--docsearch-hit-color: var(--vp-c-text-2);--docsearch-hit-shadow: none}.DocSearch-Button{display:flex;justify-content:center;align-items:center;margin:0;padding:0;width:48px;height:55px;background:transparent;transition:border-color .25s}.DocSearch-Button:hover{background:transparent}.DocSearch-Button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}.DocSearch-Button-Key--pressed{transform:none;box-shadow:none}.DocSearch-Button:focus:not(:focus-visible){outline:none!important}@media (min-width: 768px){.DocSearch-Button{justify-content:flex-start;border:1px solid transparent;border-radius:8px;padding:0 10px 0 12px;width:100%;height:40px;background-color:var(--vp-c-bg-alt)}.DocSearch-Button:hover{border-color:var(--vp-c-brand-1);background:var(--vp-c-bg-alt)}}.DocSearch-Button .DocSearch-Button-Container{display:flex;align-items:center}.DocSearch-Button .DocSearch-Search-Icon{position:relative;width:16px;height:16px;color:var(--vp-c-text-1);fill:currentColor;transition:color .5s}.DocSearch-Button:hover .DocSearch-Search-Icon{color:var(--vp-c-text-1)}@media (min-width: 768px){.DocSearch-Button .DocSearch-Search-Icon{top:1px;margin-right:8px;width:14px;height:14px;color:var(--vp-c-text-2)}}.DocSearch-Button .DocSearch-Button-Placeholder{display:none;margin-top:2px;padding:0 16px 0 0;font-size:13px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.DocSearch-Button:hover .DocSearch-Button-Placeholder{color:var(--vp-c-text-1)}@media (min-width: 768px){.DocSearch-Button .DocSearch-Button-Placeholder{display:inline-block}}.DocSearch-Button .DocSearch-Button-Keys{direction:ltr;display:none;min-width:auto}@media (min-width: 768px){.DocSearch-Button .DocSearch-Button-Keys{display:flex;align-items:center}}.DocSearch-Button .DocSearch-Button-Key{display:block;margin:2px 0 0;border:1px solid var(--vp-c-divider);border-right:none;border-radius:4px 0 0 4px;padding-left:6px;min-width:0;width:auto;height:22px;line-height:22px;font-family:var(--vp-font-family-base);font-size:12px;font-weight:500;transition:color .5s,border-color .5s}.DocSearch-Button .DocSearch-Button-Key+.DocSearch-Button-Key{border-right:1px solid var(--vp-c-divider);border-left:none;border-radius:0 4px 4px 0;padding-left:2px;padding-right:6px}.DocSearch-Button .DocSearch-Button-Key:first-child{font-size:0!important}.DocSearch-Button .DocSearch-Button-Key:first-child:after{content:"Ctrl";font-size:12px;letter-spacing:normal;color:var(--docsearch-muted-color)}.mac .DocSearch-Button .DocSearch-Button-Key:first-child:after{content:"⌘"}.DocSearch-Button .DocSearch-Button-Key:first-child>*{display:none}.DocSearch-Search-Icon{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke-width='1.6' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' d='m14.386 14.386 4.088 4.088-4.088-4.088A7.533 7.533 0 1 1 3.733 3.733a7.533 7.533 0 0 1 10.653 10.653z'/%3E%3C/svg%3E")}.VPNavBarSearch{display:flex;align-items:center}@media (min-width: 768px){.VPNavBarSearch{flex-grow:1;padding-left:24px}}@media (min-width: 960px){.VPNavBarSearch{padding-left:32px}}.dark .DocSearch-Footer{border-top:1px solid var(--vp-c-divider)}.DocSearch-Form{border:1px solid var(--vp-c-brand-1);background-color:var(--vp-c-white)}.dark .DocSearch-Form{background-color:var(--vp-c-default-soft)}.DocSearch-Screen-Icon>svg{margin:auto}.VPNavBarSocialLinks[data-v-0394ad82]{display:none}@media (min-width: 1280px){.VPNavBarSocialLinks[data-v-0394ad82]{display:flex;align-items:center}}.title[data-v-ab179fa1]{display:flex;align-items:center;border-bottom:1px solid transparent;width:100%;height:var(--vp-nav-height);font-size:16px;font-weight:600;color:var(--vp-c-text-1);transition:opacity .25s}@media (min-width: 960px){.title[data-v-ab179fa1]{flex-shrink:0}.VPNavBarTitle.has-sidebar .title[data-v-ab179fa1]{border-bottom-color:var(--vp-c-divider)}}[data-v-ab179fa1] .logo{margin-right:8px;height:var(--vp-nav-logo-height)}.VPNavBarTranslations[data-v-88af2de4]{display:none}@media (min-width: 1280px){.VPNavBarTranslations[data-v-88af2de4]{display:flex;align-items:center}}.title[data-v-88af2de4]{padding:0 24px 0 12px;line-height:32px;font-size:14px;font-weight:700;color:var(--vp-c-text-1)}.VPNavBar[data-v-ccf7ddec]{position:relative;height:var(--vp-nav-height);pointer-events:none;white-space:nowrap;transition:background-color .5s}.VPNavBar[data-v-ccf7ddec]:not(.home){background-color:var(--vp-nav-bg-color)}@media (min-width: 960px){.VPNavBar[data-v-ccf7ddec]:not(.home){background-color:transparent}.VPNavBar[data-v-ccf7ddec]:not(.has-sidebar):not(.home.top){background-color:var(--vp-nav-bg-color)}}.wrapper[data-v-ccf7ddec]{padding:0 8px 0 24px}@media (min-width: 768px){.wrapper[data-v-ccf7ddec]{padding:0 32px}}@media (min-width: 960px){.VPNavBar.has-sidebar .wrapper[data-v-ccf7ddec]{padding:0}}.container[data-v-ccf7ddec]{display:flex;justify-content:space-between;margin:0 auto;max-width:calc(var(--vp-layout-max-width) - 64px);height:var(--vp-nav-height);pointer-events:none}.container>.title[data-v-ccf7ddec],.container>.content[data-v-ccf7ddec]{pointer-events:none}.container[data-v-ccf7ddec] *{pointer-events:auto}@media (min-width: 960px){.VPNavBar.has-sidebar .container[data-v-ccf7ddec]{max-width:100%}}.title[data-v-ccf7ddec]{flex-shrink:0;height:calc(var(--vp-nav-height) - 1px);transition:background-color .5s}@media (min-width: 960px){.VPNavBar.has-sidebar .title[data-v-ccf7ddec]{position:absolute;top:0;left:0;z-index:2;padding:0 32px;width:var(--vp-sidebar-width);height:var(--vp-nav-height);background-color:transparent}}@media (min-width: 1440px){.VPNavBar.has-sidebar .title[data-v-ccf7ddec]{padding-left:max(32px,calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));width:calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px)}}.content[data-v-ccf7ddec]{flex-grow:1}@media (min-width: 960px){.VPNavBar.has-sidebar .content[data-v-ccf7ddec]{position:relative;z-index:1;padding-right:32px;padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPNavBar.has-sidebar .content[data-v-ccf7ddec]{padding-right:calc((100vw - var(--vp-layout-max-width)) / 2 + 32px);padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.content-body[data-v-ccf7ddec]{display:flex;justify-content:flex-end;align-items:center;height:var(--vp-nav-height);transition:background-color .5s}@media (min-width: 960px){.VPNavBar:not(.home.top) .content-body[data-v-ccf7ddec]{position:relative;background-color:var(--vp-nav-bg-color)}.VPNavBar:not(.has-sidebar):not(.home.top) .content-body[data-v-ccf7ddec]{background-color:transparent}}@media (max-width: 767px){.content-body[data-v-ccf7ddec]{column-gap:.5rem}}.menu+.translations[data-v-ccf7ddec]:before,.menu+.appearance[data-v-ccf7ddec]:before,.menu+.social-links[data-v-ccf7ddec]:before,.translations+.appearance[data-v-ccf7ddec]:before,.appearance+.social-links[data-v-ccf7ddec]:before{margin-right:8px;margin-left:8px;width:1px;height:24px;background-color:var(--vp-c-divider);content:""}.menu+.appearance[data-v-ccf7ddec]:before,.translations+.appearance[data-v-ccf7ddec]:before{margin-right:16px}.appearance+.social-links[data-v-ccf7ddec]:before{margin-left:16px}.social-links[data-v-ccf7ddec]{margin-right:-8px}.divider[data-v-ccf7ddec]{width:100%;height:1px}@media (min-width: 960px){.VPNavBar.has-sidebar .divider[data-v-ccf7ddec]{padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPNavBar.has-sidebar .divider[data-v-ccf7ddec]{padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.divider-line[data-v-ccf7ddec]{width:100%;height:1px;transition:background-color .5s}.VPNavBar:not(.home) .divider-line[data-v-ccf7ddec]{background-color:var(--vp-c-gutter)}@media (min-width: 960px){.VPNavBar:not(.home.top) .divider-line[data-v-ccf7ddec]{background-color:var(--vp-c-gutter)}.VPNavBar:not(.has-sidebar):not(.home.top) .divider[data-v-ccf7ddec]{background-color:var(--vp-c-gutter)}}.VPNavScreenAppearance[data-v-2d7af913]{display:flex;justify-content:space-between;align-items:center;border-radius:8px;padding:12px 14px 12px 16px;background-color:var(--vp-c-bg-soft)}.text[data-v-2d7af913]{line-height:24px;font-size:12px;font-weight:500;color:var(--vp-c-text-2)}.VPNavScreenMenuLink[data-v-7f31e1f6]{display:block;border-bottom:1px solid var(--vp-c-divider);padding:12px 0 11px;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:border-color .25s,color .25s}.VPNavScreenMenuLink[data-v-7f31e1f6]:hover{color:var(--vp-c-brand-1)}.VPNavScreenMenuGroupLink[data-v-19976ae1]{display:block;margin-left:12px;line-height:32px;font-size:14px;font-weight:400;color:var(--vp-c-text-1);transition:color .25s}.VPNavScreenMenuGroupLink[data-v-19976ae1]:hover{color:var(--vp-c-brand-1)}.VPNavScreenMenuGroupSection[data-v-8133b170]{display:block}.title[data-v-8133b170]{line-height:32px;font-size:13px;font-weight:700;color:var(--vp-c-text-2);transition:color .25s}.VPNavScreenMenuGroup[data-v-ff6087d4]{border-bottom:1px solid var(--vp-c-divider);height:48px;overflow:hidden;transition:border-color .5s}.VPNavScreenMenuGroup .items[data-v-ff6087d4]{visibility:hidden}.VPNavScreenMenuGroup.open .items[data-v-ff6087d4]{visibility:visible}.VPNavScreenMenuGroup.open[data-v-ff6087d4]{padding-bottom:10px;height:auto}.VPNavScreenMenuGroup.open .button[data-v-ff6087d4]{padding-bottom:6px;color:var(--vp-c-brand-1)}.VPNavScreenMenuGroup.open .button-icon[data-v-ff6087d4]{transform:rotate(45deg)}.button[data-v-ff6087d4]{display:flex;justify-content:space-between;align-items:center;padding:12px 4px 11px 0;width:100%;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.button[data-v-ff6087d4]:hover{color:var(--vp-c-brand-1)}.button-icon[data-v-ff6087d4]{transition:transform .25s}.group[data-v-ff6087d4]:first-child{padding-top:0}.group+.group[data-v-ff6087d4],.group+.item[data-v-ff6087d4]{padding-top:4px}.VPNavScreenTranslations[data-v-858fe1a4]{height:24px;overflow:hidden}.VPNavScreenTranslations.open[data-v-858fe1a4]{height:auto}.title[data-v-858fe1a4]{display:flex;align-items:center;font-size:14px;font-weight:500;color:var(--vp-c-text-1)}.icon[data-v-858fe1a4]{font-size:16px}.icon.lang[data-v-858fe1a4]{margin-right:8px}.icon.chevron[data-v-858fe1a4]{margin-left:4px}.list[data-v-858fe1a4]{padding:4px 0 0 24px}.link[data-v-858fe1a4]{line-height:32px;font-size:13px;color:var(--vp-c-text-1)}.VPNavScreen[data-v-cc5739dd]{position:fixed;top:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 1px);right:0;bottom:0;left:0;padding:0 32px;width:100%;background-color:var(--vp-nav-screen-bg-color);overflow-y:auto;transition:background-color .5s;pointer-events:auto}.VPNavScreen.fade-enter-active[data-v-cc5739dd],.VPNavScreen.fade-leave-active[data-v-cc5739dd]{transition:opacity .25s}.VPNavScreen.fade-enter-active .container[data-v-cc5739dd],.VPNavScreen.fade-leave-active .container[data-v-cc5739dd]{transition:transform .25s ease}.VPNavScreen.fade-enter-from[data-v-cc5739dd],.VPNavScreen.fade-leave-to[data-v-cc5739dd]{opacity:0}.VPNavScreen.fade-enter-from .container[data-v-cc5739dd],.VPNavScreen.fade-leave-to .container[data-v-cc5739dd]{transform:translateY(-8px)}@media (min-width: 768px){.VPNavScreen[data-v-cc5739dd]{display:none}}.container[data-v-cc5739dd]{margin:0 auto;padding:24px 0 96px;max-width:288px}.menu+.translations[data-v-cc5739dd],.menu+.appearance[data-v-cc5739dd],.translations+.appearance[data-v-cc5739dd]{margin-top:24px}.menu+.social-links[data-v-cc5739dd]{margin-top:16px}.appearance+.social-links[data-v-cc5739dd]{margin-top:16px}.VPNav[data-v-ae24b3ad]{position:relative;top:var(--vp-layout-top-height, 0px);left:0;z-index:var(--vp-z-index-nav);width:100%;pointer-events:none;transition:background-color .5s}@media (min-width: 960px){.VPNav[data-v-ae24b3ad]{position:fixed}}.VPSidebarItem.level-0[data-v-b8d55f3b]{padding-bottom:24px}.VPSidebarItem.collapsed.level-0[data-v-b8d55f3b]{padding-bottom:10px}.item[data-v-b8d55f3b]{position:relative;display:flex;width:100%}.VPSidebarItem.collapsible>.item[data-v-b8d55f3b]{cursor:pointer}.indicator[data-v-b8d55f3b]{position:absolute;top:6px;bottom:6px;left:-17px;width:2px;border-radius:2px;transition:background-color .25s}.VPSidebarItem.level-2.is-active>.item>.indicator[data-v-b8d55f3b],.VPSidebarItem.level-3.is-active>.item>.indicator[data-v-b8d55f3b],.VPSidebarItem.level-4.is-active>.item>.indicator[data-v-b8d55f3b],.VPSidebarItem.level-5.is-active>.item>.indicator[data-v-b8d55f3b]{background-color:var(--vp-c-brand-1)}.link[data-v-b8d55f3b]{display:flex;align-items:center;flex-grow:1}.text[data-v-b8d55f3b]{flex-grow:1;padding:4px 0;line-height:24px;font-size:14px;transition:color .25s}.VPSidebarItem.level-0 .text[data-v-b8d55f3b]{font-weight:700;color:var(--vp-c-text-1)}.VPSidebarItem.level-1 .text[data-v-b8d55f3b],.VPSidebarItem.level-2 .text[data-v-b8d55f3b],.VPSidebarItem.level-3 .text[data-v-b8d55f3b],.VPSidebarItem.level-4 .text[data-v-b8d55f3b],.VPSidebarItem.level-5 .text[data-v-b8d55f3b]{font-weight:500;color:var(--vp-c-text-2)}.VPSidebarItem.level-0.is-link>.item>.link:hover .text[data-v-b8d55f3b],.VPSidebarItem.level-1.is-link>.item>.link:hover .text[data-v-b8d55f3b],.VPSidebarItem.level-2.is-link>.item>.link:hover .text[data-v-b8d55f3b],.VPSidebarItem.level-3.is-link>.item>.link:hover .text[data-v-b8d55f3b],.VPSidebarItem.level-4.is-link>.item>.link:hover .text[data-v-b8d55f3b],.VPSidebarItem.level-5.is-link>.item>.link:hover .text[data-v-b8d55f3b]{color:var(--vp-c-brand-1)}.VPSidebarItem.level-0.has-active>.item>.text[data-v-b8d55f3b],.VPSidebarItem.level-1.has-active>.item>.text[data-v-b8d55f3b],.VPSidebarItem.level-2.has-active>.item>.text[data-v-b8d55f3b],.VPSidebarItem.level-3.has-active>.item>.text[data-v-b8d55f3b],.VPSidebarItem.level-4.has-active>.item>.text[data-v-b8d55f3b],.VPSidebarItem.level-5.has-active>.item>.text[data-v-b8d55f3b],.VPSidebarItem.level-0.has-active>.item>.link>.text[data-v-b8d55f3b],.VPSidebarItem.level-1.has-active>.item>.link>.text[data-v-b8d55f3b],.VPSidebarItem.level-2.has-active>.item>.link>.text[data-v-b8d55f3b],.VPSidebarItem.level-3.has-active>.item>.link>.text[data-v-b8d55f3b],.VPSidebarItem.level-4.has-active>.item>.link>.text[data-v-b8d55f3b],.VPSidebarItem.level-5.has-active>.item>.link>.text[data-v-b8d55f3b]{color:var(--vp-c-text-1)}.VPSidebarItem.level-0.is-active>.item .link>.text[data-v-b8d55f3b],.VPSidebarItem.level-1.is-active>.item .link>.text[data-v-b8d55f3b],.VPSidebarItem.level-2.is-active>.item .link>.text[data-v-b8d55f3b],.VPSidebarItem.level-3.is-active>.item .link>.text[data-v-b8d55f3b],.VPSidebarItem.level-4.is-active>.item .link>.text[data-v-b8d55f3b],.VPSidebarItem.level-5.is-active>.item .link>.text[data-v-b8d55f3b]{color:var(--vp-c-brand-1)}.caret[data-v-b8d55f3b]{display:flex;justify-content:center;align-items:center;margin-right:-7px;width:32px;height:32px;color:var(--vp-c-text-3);cursor:pointer;transition:color .25s;flex-shrink:0}.item:hover .caret[data-v-b8d55f3b]{color:var(--vp-c-text-2)}.item:hover .caret[data-v-b8d55f3b]:hover{color:var(--vp-c-text-1)}.caret-icon[data-v-b8d55f3b]{font-size:18px;transform:rotate(90deg);transition:transform .25s}.VPSidebarItem.collapsed .caret-icon[data-v-b8d55f3b]{transform:rotate(0)}.VPSidebarItem.level-1 .items[data-v-b8d55f3b],.VPSidebarItem.level-2 .items[data-v-b8d55f3b],.VPSidebarItem.level-3 .items[data-v-b8d55f3b],.VPSidebarItem.level-4 .items[data-v-b8d55f3b],.VPSidebarItem.level-5 .items[data-v-b8d55f3b]{border-left:1px solid var(--vp-c-divider);padding-left:16px}.VPSidebarItem.collapsed .items[data-v-b8d55f3b]{display:none}.VPSidebar[data-v-575e6a36]{position:fixed;top:var(--vp-layout-top-height, 0px);bottom:0;left:0;z-index:var(--vp-z-index-sidebar);padding:32px 32px 96px;width:calc(100vw - 64px);max-width:320px;background-color:var(--vp-sidebar-bg-color);opacity:0;box-shadow:var(--vp-c-shadow-3);overflow-x:hidden;overflow-y:auto;transform:translate(-100%);transition:opacity .5s,transform .25s ease;overscroll-behavior:contain}.VPSidebar.open[data-v-575e6a36]{opacity:1;visibility:visible;transform:translate(0);transition:opacity .25s,transform .5s cubic-bezier(.19,1,.22,1)}.dark .VPSidebar[data-v-575e6a36]{box-shadow:var(--vp-shadow-1)}@media (min-width: 960px){.VPSidebar[data-v-575e6a36]{padding-top:var(--vp-nav-height);width:var(--vp-sidebar-width);max-width:100%;background-color:var(--vp-sidebar-bg-color);opacity:1;visibility:visible;box-shadow:none;transform:translate(0)}}@media (min-width: 1440px){.VPSidebar[data-v-575e6a36]{padding-left:max(32px,calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));width:calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px)}}@media (min-width: 960px){.curtain[data-v-575e6a36]{position:sticky;top:-64px;left:0;z-index:1;margin-top:calc(var(--vp-nav-height) * -1);margin-right:-32px;margin-left:-32px;height:var(--vp-nav-height);background-color:var(--vp-sidebar-bg-color)}}.nav[data-v-575e6a36]{outline:0}.group+.group[data-v-575e6a36]{border-top:1px solid var(--vp-c-divider);padding-top:10px}@media (min-width: 960px){.group[data-v-575e6a36]{padding-top:10px;width:calc(var(--vp-sidebar-width) - 64px)}}.VPSkipLink[data-v-0f60ec36]{top:8px;left:8px;padding:8px 16px;z-index:999;border-radius:8px;font-size:12px;font-weight:700;text-decoration:none;color:var(--vp-c-brand-1);box-shadow:var(--vp-shadow-3);background-color:var(--vp-c-bg)}.VPSkipLink[data-v-0f60ec36]:focus{height:auto;width:auto;clip:auto;clip-path:none}@media (min-width: 1280px){.VPSkipLink[data-v-0f60ec36]{top:14px;left:16px}}.Layout[data-v-5d98c3a5]{display:flex;flex-direction:column;min-height:100vh}.VPHomeSponsors[data-v-3d121b4a]{border-top:1px solid var(--vp-c-gutter);padding-top:88px!important}.VPHomeSponsors[data-v-3d121b4a]{margin:96px 0}@media (min-width: 768px){.VPHomeSponsors[data-v-3d121b4a]{margin:128px 0}}.VPHomeSponsors[data-v-3d121b4a]{padding:0 24px}@media (min-width: 768px){.VPHomeSponsors[data-v-3d121b4a]{padding:0 48px}}@media (min-width: 960px){.VPHomeSponsors[data-v-3d121b4a]{padding:0 64px}}.container[data-v-3d121b4a]{margin:0 auto;max-width:1152px}.love[data-v-3d121b4a]{margin:0 auto;width:fit-content;font-size:28px;color:var(--vp-c-text-3)}.icon[data-v-3d121b4a]{display:inline-block}.message[data-v-3d121b4a]{margin:0 auto;padding-top:10px;max-width:320px;text-align:center;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}.sponsors[data-v-3d121b4a]{padding-top:32px}.action[data-v-3d121b4a]{padding-top:40px;text-align:center}.VPTeamPage[data-v-7c57f839]{margin:96px 0}@media (min-width: 768px){.VPTeamPage[data-v-7c57f839]{margin:128px 0}}.VPHome .VPTeamPageTitle[data-v-7c57f839-s]{border-top:1px solid var(--vp-c-gutter);padding-top:88px!important}.VPTeamPageSection+.VPTeamPageSection[data-v-7c57f839-s],.VPTeamMembers+.VPTeamPageSection[data-v-7c57f839-s]{margin-top:64px}.VPTeamMembers+.VPTeamMembers[data-v-7c57f839-s]{margin-top:24px}@media (min-width: 768px){.VPTeamPageTitle+.VPTeamPageSection[data-v-7c57f839-s]{margin-top:16px}.VPTeamPageSection+.VPTeamPageSection[data-v-7c57f839-s],.VPTeamMembers+.VPTeamPageSection[data-v-7c57f839-s]{margin-top:96px}}.VPTeamMembers[data-v-7c57f839-s]{padding:0 24px}@media (min-width: 768px){.VPTeamMembers[data-v-7c57f839-s]{padding:0 48px}}@media (min-width: 960px){.VPTeamMembers[data-v-7c57f839-s]{padding:0 64px}}.VPTeamPageTitle[data-v-bf2cbdac]{padding:48px 32px;text-align:center}@media (min-width: 768px){.VPTeamPageTitle[data-v-bf2cbdac]{padding:64px 48px 48px}}@media (min-width: 960px){.VPTeamPageTitle[data-v-bf2cbdac]{padding:80px 64px 48px}}.title[data-v-bf2cbdac]{letter-spacing:0;line-height:44px;font-size:36px;font-weight:500}@media (min-width: 768px){.title[data-v-bf2cbdac]{letter-spacing:-.5px;line-height:56px;font-size:48px}}.lead[data-v-bf2cbdac]{margin:0 auto;max-width:512px;padding-top:12px;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}@media (min-width: 768px){.lead[data-v-bf2cbdac]{max-width:592px;letter-spacing:.15px;line-height:28px;font-size:20px}}.VPTeamPageSection[data-v-b1a88750]{padding:0 32px}@media (min-width: 768px){.VPTeamPageSection[data-v-b1a88750]{padding:0 48px}}@media (min-width: 960px){.VPTeamPageSection[data-v-b1a88750]{padding:0 64px}}.title[data-v-b1a88750]{position:relative;margin:0 auto;max-width:1152px;text-align:center;color:var(--vp-c-text-2)}.title-line[data-v-b1a88750]{position:absolute;top:16px;left:0;width:100%;height:1px;background-color:var(--vp-c-divider)}.title-text[data-v-b1a88750]{position:relative;display:inline-block;padding:0 24px;letter-spacing:0;line-height:32px;font-size:20px;font-weight:500;background-color:var(--vp-c-bg)}.lead[data-v-b1a88750]{margin:0 auto;max-width:480px;padding-top:12px;text-align:center;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}.members[data-v-b1a88750]{padding-top:40px}.VPTeamMembersItem[data-v-f3fa364a]{display:flex;flex-direction:column;gap:2px;border-radius:12px;width:100%;height:100%;overflow:hidden}.VPTeamMembersItem.small .profile[data-v-f3fa364a]{padding:32px}.VPTeamMembersItem.small .data[data-v-f3fa364a]{padding-top:20px}.VPTeamMembersItem.small .avatar[data-v-f3fa364a]{width:64px;height:64px}.VPTeamMembersItem.small .name[data-v-f3fa364a]{line-height:24px;font-size:16px}.VPTeamMembersItem.small .affiliation[data-v-f3fa364a]{padding-top:4px;line-height:20px;font-size:14px}.VPTeamMembersItem.small .desc[data-v-f3fa364a]{padding-top:12px;line-height:20px;font-size:14px}.VPTeamMembersItem.small .links[data-v-f3fa364a]{margin:0 -16px -20px;padding:10px 0 0}.VPTeamMembersItem.medium .profile[data-v-f3fa364a]{padding:48px 32px}.VPTeamMembersItem.medium .data[data-v-f3fa364a]{padding-top:24px;text-align:center}.VPTeamMembersItem.medium .avatar[data-v-f3fa364a]{width:96px;height:96px}.VPTeamMembersItem.medium .name[data-v-f3fa364a]{letter-spacing:.15px;line-height:28px;font-size:20px}.VPTeamMembersItem.medium .affiliation[data-v-f3fa364a]{padding-top:4px;font-size:16px}.VPTeamMembersItem.medium .desc[data-v-f3fa364a]{padding-top:16px;max-width:288px;font-size:16px}.VPTeamMembersItem.medium .links[data-v-f3fa364a]{margin:0 -16px -12px;padding:16px 12px 0}.profile[data-v-f3fa364a]{flex-grow:1;background-color:var(--vp-c-bg-soft)}.data[data-v-f3fa364a]{text-align:center}.avatar[data-v-f3fa364a]{position:relative;flex-shrink:0;margin:0 auto;border-radius:50%;box-shadow:var(--vp-shadow-3)}.avatar-img[data-v-f3fa364a]{position:absolute;top:0;right:0;bottom:0;left:0;border-radius:50%;object-fit:cover}.name[data-v-f3fa364a]{margin:0;font-weight:600}.affiliation[data-v-f3fa364a]{margin:0;font-weight:500;color:var(--vp-c-text-2)}.org.link[data-v-f3fa364a]{color:var(--vp-c-text-2);transition:color .25s}.org.link[data-v-f3fa364a]:hover{color:var(--vp-c-brand-1)}.desc[data-v-f3fa364a]{margin:0 auto}.desc[data-v-f3fa364a] a{font-weight:500;color:var(--vp-c-brand-1);text-decoration-style:dotted;transition:color .25s}.links[data-v-f3fa364a]{display:flex;justify-content:center;height:56px}.sp-link[data-v-f3fa364a]{display:flex;justify-content:center;align-items:center;text-align:center;padding:16px;font-size:14px;font-weight:500;color:var(--vp-c-sponsor);background-color:var(--vp-c-bg-soft);transition:color .25s,background-color .25s}.sp .sp-link.link[data-v-f3fa364a]:hover,.sp .sp-link.link[data-v-f3fa364a]:focus{outline:none;color:var(--vp-c-white);background-color:var(--vp-c-sponsor)}.sp-icon[data-v-f3fa364a]{margin-right:8px;font-size:16px}.VPTeamMembers.small .container[data-v-6cb0dbc4]{grid-template-columns:repeat(auto-fit,minmax(224px,1fr))}.VPTeamMembers.small.count-1 .container[data-v-6cb0dbc4]{max-width:276px}.VPTeamMembers.small.count-2 .container[data-v-6cb0dbc4]{max-width:576px}.VPTeamMembers.small.count-3 .container[data-v-6cb0dbc4]{max-width:876px}.VPTeamMembers.medium .container[data-v-6cb0dbc4]{grid-template-columns:repeat(auto-fit,minmax(256px,1fr))}@media (min-width: 375px){.VPTeamMembers.medium .container[data-v-6cb0dbc4]{grid-template-columns:repeat(auto-fit,minmax(288px,1fr))}}.VPTeamMembers.medium.count-1 .container[data-v-6cb0dbc4]{max-width:368px}.VPTeamMembers.medium.count-2 .container[data-v-6cb0dbc4]{max-width:760px}.container[data-v-6cb0dbc4]{display:grid;gap:24px;margin:0 auto;max-width:1152px}:root{--vp-nolebase-highlight-targeted-heading-color: var(--vp-custom-block-tip-text);--vp-nolebase-highlight-targeted-heading-bg: var(--vp-custom-block-tip-bg)}@keyframes vp-nolebase-highlight-targeted-heading-animation{0%{background-color:transparent;box-shadow:0 0 0 8px transparent}10%,35%{color:var(--vp-nolebase-highlight-targeted-heading-color);border-color:transparent;border-radius:4px;background-color:var(--vp-nolebase-highlight-targeted-heading-bg);box-shadow:0 0 0 8px var(--vp-nolebase-highlight-targeted-heading-bg)}99%{background-color:transparent;border-radius:4px;box-shadow:0 0 0 8px transparent}to{border-radius:0;background-color:transparent;box-shadow:none}}.VPNolebaseHighlightTargetedHeadingAnimated{animation:vp-nolebase-highlight-targeted-heading-animation 1.5s ease-in-out}*,:before,:after{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / .5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }::backdrop{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / .5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }@font-face{font-family:"Baloo 2";font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/baloo2/v21/wXK0E3kTposypRydzVT08TS3JnAmtdgazZpp_led7Q.woff2) format("woff2");unicode-range:U+0900-097F,U+1CD0-1CF9,U+200C-200D,U+20A8,U+20B9,U+20F0,U+25CC,U+A830-A839,U+A8E0-A8FF,U+11B00-11B09}@font-face{font-family:"Baloo 2";font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/baloo2/v21/wXK0E3kTposypRydzVT08TS3JnAmtdgazZpn_led7Q.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:"Baloo 2";font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/baloo2/v21/wXK0E3kTposypRydzVT08TS3JnAmtdgazZpm_led7Q.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:"Baloo 2";font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/baloo2/v21/wXK0E3kTposypRydzVT08TS3JnAmtdgazZpo_lc.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Chakra Petch;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/chakrapetch/v11/cIf6MapbsEk7TDLdtEz1BwkWi6pgeL4.woff2) format("woff2");unicode-range:U+0E01-0E5B,U+200C-200D,U+25CC}@font-face{font-family:Chakra Petch;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/chakrapetch/v11/cIf6MapbsEk7TDLdtEz1BwkWkKpgeL4.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Chakra Petch;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/chakrapetch/v11/cIf6MapbsEk7TDLdtEz1BwkWkapgeL4.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Chakra Petch;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/chakrapetch/v11/cIf6MapbsEk7TDLdtEz1BwkWn6pg.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Jura;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/jura/v31/z7NOdRfiaC4Vd8hhoPzfb5vBTP1d7ZurR_ibHw.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Jura;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/jura/v31/z7NOdRfiaC4Vd8hhoPzfb5vBTP1d7ZuiR_ibHw.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Jura;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/jura/v31/z7NOdRfiaC4Vd8hhoPzfb5vBTP1d7ZuqR_ibHw.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Jura;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/jura/v31/z7NOdRfiaC4Vd8hhoPzfb5vBTP1d7ZulR_ibHw.woff2) format("woff2");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:Jura;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/jura/v31/z7NOdRfiaC4Vd8hhoPzfb5vBTP1d7ZvuR_ibHw.woff2) format("woff2");unicode-range:U+200C-200D,U+2010,U+25CC,U+A900-A92F}@font-face{font-family:Jura;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/jura/v31/z7NOdRfiaC4Vd8hhoPzfb5vBTP1d7ZupR_ibHw.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Jura;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/jura/v31/z7NOdRfiaC4Vd8hhoPzfb5vBTP1d7ZuoR_ibHw.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Jura;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/jura/v31/z7NOdRfiaC4Vd8hhoPzfb5vBTP1d7ZumR_g.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Noto Sans;font-style:normal;font-weight:400;font-stretch:normal;font-display:swap;src:url(https://fonts.gstatic.com/s/notosans/v36/o-0mIpQlx3QUlC5A4PNB6Ryti20_6n1iPHjcz6L1SoM-jCpoiyD9A-9X6VLKzA.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Noto Sans;font-style:normal;font-weight:400;font-stretch:normal;font-display:swap;src:url(https://fonts.gstatic.com/s/notosans/v36/o-0mIpQlx3QUlC5A4PNB6Ryti20_6n1iPHjcz6L1SoM-jCpoiyD9A-9e6VLKzA.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Noto Sans;font-style:normal;font-weight:400;font-stretch:normal;font-display:swap;src:url(https://fonts.gstatic.com/s/notosans/v36/o-0mIpQlx3QUlC5A4PNB6Ryti20_6n1iPHjcz6L1SoM-jCpoiyD9A-9b6VLKzA.woff2) format("woff2");unicode-range:U+0900-097F,U+1CD0-1CF9,U+200C-200D,U+20A8,U+20B9,U+20F0,U+25CC,U+A830-A839,U+A8E0-A8FF,U+11B00-11B09}@font-face{font-family:Noto Sans;font-style:normal;font-weight:400;font-stretch:normal;font-display:swap;src:url(https://fonts.gstatic.com/s/notosans/v36/o-0mIpQlx3QUlC5A4PNB6Ryti20_6n1iPHjcz6L1SoM-jCpoiyD9A-9W6VLKzA.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Noto Sans;font-style:normal;font-weight:400;font-stretch:normal;font-display:swap;src:url(https://fonts.gstatic.com/s/notosans/v36/o-0mIpQlx3QUlC5A4PNB6Ryti20_6n1iPHjcz6L1SoM-jCpoiyD9A-9Z6VLKzA.woff2) format("woff2");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:Noto Sans;font-style:normal;font-weight:400;font-stretch:normal;font-display:swap;src:url(https://fonts.gstatic.com/s/notosans/v36/o-0mIpQlx3QUlC5A4PNB6Ryti20_6n1iPHjcz6L1SoM-jCpoiyD9A-9V6VLKzA.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Noto Sans;font-style:normal;font-weight:400;font-stretch:normal;font-display:swap;src:url(https://fonts.gstatic.com/s/notosans/v36/o-0mIpQlx3QUlC5A4PNB6Ryti20_6n1iPHjcz6L1SoM-jCpoiyD9A-9U6VLKzA.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Noto Sans;font-style:normal;font-weight:400;font-stretch:normal;font-display:swap;src:url(https://fonts.gstatic.com/s/notosans/v36/o-0mIpQlx3QUlC5A4PNB6Ryti20_6n1iPHjcz6L1SoM-jCpoiyD9A-9a6VI.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Roboto;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu72xKOzY.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Roboto;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu5mxKOzY.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Roboto;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7mxKOzY.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Roboto;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4WxKOzY.woff2) format("woff2");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:Roboto;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7WxKOzY.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Roboto;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu7GxKOzY.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Roboto;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Mu4mxK.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-cyrillic.C5lxZ8CY.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-greek-ext.CqjqNYQ-.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-greek.BBVDIX6e.woff2) format("woff2");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-vietnamese.BjW4sHH5.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-latin-ext.4ZJIpNVo.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-latin.Di8DUHzh.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-cyrillic-ext.r48I6akx.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-cyrillic.By2_1cv3.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-greek-ext.1u6EdAuj.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-greek.DJ8dCoTZ.woff2) format("woff2");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-vietnamese.BSbpV94h.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-latin-ext.CN1xVJS-.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-latin.C2AdPX0b.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Punctuation SC;font-weight:400;src:local("PingFang SC Regular"),local("Noto Sans CJK SC"),local("Microsoft YaHei");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}@font-face{font-family:Punctuation SC;font-weight:500;src:local("PingFang SC Medium"),local("Noto Sans CJK SC"),local("Microsoft YaHei");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}@font-face{font-family:Punctuation SC;font-weight:600;src:local("PingFang SC Semibold"),local("Noto Sans CJK SC Bold"),local("Microsoft YaHei Bold");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}@font-face{font-family:Punctuation SC;font-weight:700;src:local("PingFang SC Semibold"),local("Noto Sans CJK SC Bold"),local("Microsoft YaHei Bold");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}html{overflow-x:hidden}:root{--vp-c-bg: #3B4252;--vp-c-bg-elv: #434C5E;--vp-font-family-base: Itim;--vp-font-family-mono: Roboto Mono;--vp-layout-max-width: 1080px;--vp-nav-height: 48px;--vp-local-search-bg: var(--vp-c-bg-alt)}footer{color:var(--vp-c-default-1)}footer a[href^=http]:after{color:var(--vp-c-border)!important}.title{justify-content:center;border:none!important;position:unset!important;padding:0!important;width:unset!important}.title span{font-size:x-large}.search{padding-left:0;display:flex;flex-grow:0!important;padding-left:unset!important}.DocSearch-Button{margin:auto;width:unset;border:none!important}.DocSearch-Button-Placeholder{margin-top:unset!important;padding:unset!important;font-size:unset!important;font-weight:unset!important;color:unset!important;margin-right:8px}.VPNavBarMenu{align-items:flex-end}.VPNavBarMenuLink{line-height:unset!important;font-size:unset!important;font-weight:unset!important;color:unset!important}ul>li>ul{position:relative}ul>li>ul:before{position:absolute;content:"";width:2px;background:var(--vp-c-text-1);opacity:.3;left:-16px;top:8px;bottom:8px}.aside{display:none!important}.img-container{padding:15px;position:relative;height:11lh;width:fit-content;margin:auto}.img-container img{clip-path:polygon(18px 0%,100% 0,100% calc(100% - 18px),calc(100% - 18px) 100%,0 100%,0% 18px);height:100%;object-fit:contain;background:#fff}.img-container:after,.img-container:before{content:"";display:block;position:absolute;border:50px solid transparent;transform:rotate(135deg)}.img-container:after{bottom:-60px;right:-65px;box-shadow:0 7px 6px -9px #000}.img-container:before{top:-60px;left:-65px;box-shadow:0 -7px 6px -9px #000}.VPDoc{padding:0 32px!important}.VPDoc .container{position:relative}.VPDoc .container:before{content:"";position:absolute;top:0;bottom:0;left:0;width:30px;background:radial-gradient(5px 5px at 50% 50%,var(--vp-c-bg) 0%,var(--vp-c-bg) 100%,#0000 100%);background-size:100% 30px}.VPDoc .container:after{content:"";position:absolute;top:0;bottom:0;left:-15px;width:30px;z-index:1;background:linear-gradient(to bottom,transparent 11px,#333 11px,#333 13px,transparent 13px,transparent 17px,#333 17px,#333 19px,transparent 19px);background-size:100% 30px}.vp-doc a{color:unset;text-decoration:unset;font-weight:unset;text-underline-offset:unset;margin:0 -.4em;padding:.1em .4em;border-radius:.8em .3em;background:transparent;background-image:linear-gradient(to right,#ffe1000d,#ffe10059 4%,#ffe10026);-webkit-box-decoration-break:clone;box-decoration-break:clone}.vp-doc a:hover{color:unset;background-image:linear-gradient(to right,#ffe1001a,#ffe100b3 4%,#ffe1004d)}.vp-doc a[href^=http]:after{content:"";display:inline-block;margin-top:-1px;margin-left:4px;width:11px;height:11px;background:currentColor;color:var(--vp-c-text-3);flex-shrink:0;--icon: url("data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' %3E%3Cpath d='M0 0h24v24H0V0z' fill='none' /%3E%3Cpath d='M9 5v2h6.59L4 18.59 5.41 20 17 8.41V15h2V5H9z' /%3E%3C/svg%3E");-webkit-mask-image:var(--icon);mask-image:var(--icon)}.VPNav{left:96px!important;right:32px!important;width:unset!important;position:absolute!important;overflow:hidden}.wrapper{padding:0!important}.VPNavBar{background-color:unset!important}.VPNav .container{align-items:flex-end}.VPNav .content{padding:0!important}.VPNav .content-body{height:unset!important;align-items:flex-end!important;column-gap:unset!important}.VPNavBarHamburger{width:unset!important}.title{height:unset!important}a.title,.VPNavBarMenuLink,.VPNavBarSocialLinks a,.DocSearch-Button,.VPNav button{height:36px!important;border-radius:10px 10px 0 0;padding:8px 8px 16px!important;margin-bottom:-8px!important}.VPNav a:hover,.DocSearch-Button:hover,.VPNav button:hover{margin-bottom:unset!important}a.title{background-color:#0ff}.DocSearch-Button{background-color:#ff0!important}.VPNav .VPNavBarMenuLink[href="https://moddingtree.com"]{background-color:#0f0}.VPNav .VPNavBarMenuLink[href="https://incremental.social"]{background:#f0f}.VPNav button{background:red}.VPNav .VPNavBarSocialLinks [href="https://code.incremental.social/thepaperpilot"]{background:#f70}.VPNav .VPNavBarSocialLinks [href="https://matrix.to/#/@thepaperpilot:incremental.social"]{background:#3c9a3c}.VPNav .VPNavBarSocialLinks [href="https://incremental.social/u/thepaperpilot"]{background:#a75aff}.VPNav .divider{display:none!important}.VPSocialLinks{align-items:flex-end!important;margin-right:0!important}.VPSocialLinks:before{display:none}.VPNavBarExtra{display:none!important}.VPNavBarSocialLinks{display:flex!important}.VPNavScreenSocialLinks a,.VPNavScreenMenuLink,.VPNavScreenMenuLink:after{color:var(--vp-c-bg-alt)!important}@media (max-width: 500px){.VPNavBarSocialLinks{display:none!important}}@media (min-width: 501px){.VPNavScreenSocialLinks{display:none!important}}@media (max-width: 400px){.title span{width:60px}.title span:before{content:"Home ."}}.VPContent{padding-top:0!important;margin-top:var(--vp-nav-height)!important;padding-right:calc((100vw - var(--vp-layout-max-width)) / 2)!important;padding-left:calc((100vw - var(--vp-layout-max-width)) / 2)!important}@media (min-width: 960px){.VPNav{right:calc(max(0px,(100vw - var(--vp-layout-max-width)) / 2) + 32px)!important;left:calc(max(-15px,(100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width)) + 32px)!important}.VPContent{padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))!important}}.vp-doc .header-anchor{margin-left:calc(-1em - 23px)}.vp-doc .header-anchor{top:0!important}.VPSidebar{opacity:1!important;transition:.5s ease-out!important;box-shadow:0 0 10px 1px #0003!important}.VPLocalNav{position:fixed!important;border-bottom:none!important;background-color:unset!important;pointer-events:none}.VPLocalNav .container{align-items:flex-start!important;flex-direction:column!important}.VPLocalNav>.container>*{pointer-events:all}.VPLocalNav .menu{background:#7afcff;box-shadow:0 0 5px 1px #0003;margin-top:10px;height:30px;width:90px;padding:0 0 0 8px!important}.VPLocalNav button:not(.menu){background:#ff7eb9;padding:4px 30px 4px 8px;box-shadow:0 0 5px 1px #0003}.outline-marker{left:16px!important}.VPLocalNavOutlineDropdown{padding:0!important;margin-top:10px}.VPLocalNavOutlineDropdown button{padding:0!important;width:90px;height:30px}.curtain{display:none}@media (max-width: 840px){.DocSearch-Button-Keys{display:none!important}}@media (max-width: 959px){.VPSidebar{margin-left:-1000px!important;padding:30px 30px 30px 1030px!important;box-sizing:content-box;background:linear-gradient(to bottom,var(--vp-sidebar-bg-color) 29px,var(--vp-c-divider) 1px);background-size:100% 30px;line-height:30px;width:calc(100vw - 128px)}}.VPLocalNavOutlineDropdown .items{background:linear-gradient(to bottom,var(--vp-sidebar-bg-color) 29px,var(--vp-c-divider) 1px);background-size:100% 30px;top:85px;border-radius:0}.VPLocalNavOutlineDropdown ul>li>ul:before{left:0}.VPLocalNavOutlineDropdown .header,.VPLocalNavOutlineDropdown .outline{background:none!important;padding:0!important}.VPLocalNavOutlineDropdown .top-link,.VPLocalNavOutlineDropdown .outline-link{line-height:30px!important;font-size:unset!important;font-weight:unset!important}.aside-curtain{display:none!important}@media (min-width: 960px){.VPSidebar{transform:rotate(1.4deg)!important;top:1em!important;bottom:unset!important;--vp-sidebar-width: 250px !important;background:#feff9c!important;padding:30px!important;width:var(--vp-sidebar-width)!important;margin-left:max(-15px,calc((100% - (var(--vp-layout-max-width) - 60px)) / 2))!important;max-height:40vh;transition-duration:0s!important}.VPLocalNavOutlineDropdown{display:none}.VPDoc .aside{display:block!important;transform:rotate(1.4deg)!important;position:fixed;top:calc(40vh + 2em);left:0;--vp-sidebar-width: 250px !important;background:#feff9c!important;width:var(--vp-sidebar-width)!important;padding:0!important;margin-left:max(-15px,calc((100% - (var(--vp-layout-max-width) - 60px)) / 2))!important;max-height:40vh;overflow-y:auto}.VPDoc .aside-container{position:unset!important;height:unset!important;overflow:unset!important;padding-top:unset!important;width:unset!important}.VPDoc .aside-content{min-height:unset!important;padding:0!important}.VPDoc .aside-content .content{padding:30px!important}.outline-title{font-size:14px;font-weight:700!important;line-height:30px!important}.VPDoc .aside ul>li>ul:before{display:none}}.VPContent .container{background:linear-gradient(to bottom,var(--vp-sidebar-bg-color) 29px,var(--vp-c-divider) 1px);background-size:100% 30px;line-height:30px;box-shadow:0 0 10px 1px #0003!important}.VPContent .content{padding:0 30px!important}.content-container{border-left:double 7px var(--vp-c-divider);padding:30px 0 30px 8px;max-width:unset!important}article{padding-top:30px}.vp-doc .h-feed article{padding-top:0!important}.vp-doc h2+.e-content{margin-top:30px!important}.VPDoc h1,.VPDoc h2,.VPDoc h3,.VPDoc h4,.VPDoc h5,.VPDoc h6{margin:0!important;padding:0!important;line-height:30px!important}.VPDoc h1+p{margin-top:0!important}.VPDoc h2,.VPDoc h3,.VPDoc h4,.VPDoc h5,.VPDoc h6{margin-top:30px!important;margin-bottom:-30px!important;border:none!important}ul{margin:0!important}li+li{margin:0!important}.VPDoc p{padding:0!important;margin:30px 0!important;line-height:30px!important}blockquote{margin:30px 0!important}blockquote:first-child,blockquote:first-child p{margin-top:0!important}.VPDoc :has(+hr),.VPDoc :has(+h2),.VPDoc :has(+h3),.VPDoc :has(+h4),.VPDoc :has(+h5),.VPDoc :has(+h6),.VPDoc :has(+ul){margin-bottom:0!important}hr{margin-top:-3px!important;margin-bottom:-7px!important;border-top-style:solid!important;border-top-width:10px!important;border-image:url(/button.svg) 10 10 10 10 stretch stretch!important;height:0px!important}.text{line-height:30px!important;padding:0!important;margin:0!important}.group{padding-top:0!important}.group+.group{border-top-style:solid!important;border-top-width:10px!important;border-image:url(/button.svg) 10 10 10 10 stretch stretch!important;padding-top:23px!important;margin-top:-3px!important}table{margin:30px 0!important}#app .vp-doc tr{background-color:var(--vp-c-gray-2)}#app .vp-doc tr:nth-child(2n){background-color:var(--vp-c-bg-soft)}#app .vp-doc th,#app .vp-doc td{font-size:unset!important;font-weight:unset!important;color:unset!important;padding:0 8px!important;line-height:29px}.VPSidebarItem{padding-bottom:0!important}p:last-child{margin-bottom:0!important}.hero{width:60%;margin:auto}footer img{height:1lh;display:inline;border-radius:50%;margin:0 .25em;vertical-align:bottom}@property --anim-bg{syntax: ""; initial-value: transparent; inherits: false;}@keyframes vp-nolebase-highlight-targeted-heading-animation{0%{--anim-bg: transparent}10%,35%{--anim-bg: var(--vp-c-brand-soft)}99%{--anim-bg: transparent}to{--anim-bg: transparent}}.VPNolebaseHighlightTargetedHeadingAnimated{animation:vp-nolebase-highlight-targeted-heading-animation 1.5s ease-in-out;background:linear-gradient(0deg,var(--anim-bg) 55%,transparent 45%) repeat-x}.title-icon{line-height:30px}.excerpt{margin:8px 0!important;background:var(--docsearch-searchbox-background)}.excerpt-gradient-top{background:var(--docsearch-searchbox-background)!important;opacity:.5;clip-path:polygon(0% 0%,5% 100%,10% 0%,15% 100%,20% 0%,25% 100%,30% 0%,35% 100%,40% 0%,45% 100%,50% 0%,55% 100%,60% 0%,65% 100%,70% 0%,75% 100%,80% 0%,85% 100%,90% 0%,95% 100%,100% 0%);transform:translateY(-7px) rotate(180deg)}.excerpt-gradient-bottom{background:var(--docsearch-searchbox-background)!important;opacity:.5;clip-path:polygon(0% 0%,5% 100%,10% 0%,15% 100%,20% 0%,25% 100%,30% 0%,35% 100%,40% 0%,45% 100%,50% 0%,55% 100%,60% 0%,65% 100%,70% 0%,75% 100%,80% 0%,85% 100%,90% 0%,95% 100%,100% 0%);transform:translateY(7px)}.selected .excerpt-gradient-top,.selected .excerpt-gradient-bottom{opacity:1}.vp-doc details{border-bottom:solid 1px var(--vp-c-border)!important;margin-bottom:-1px!important}.vp-doc details a{margin-right:8px!important}.vp-doc summary{margin:29px 0 0!important;border-top:solid 1px var(--vp-c-border)!important;cursor:pointer!important}.background[data-v-4f9a2448]{position:fixed;top:0;left:0;right:0;bottom:0;z-index:-1;overflow:hidden}footer[data-v-4f9a2448]{padding:2em;z-index:26;position:relative;font-size:small;background:var(--vp-c-bg-elv)}.hero-wrapper[data-v-a285fdae]{height:16lh;position:relative}@media (max-width: 700px){.hero-wrapper[data-v-a285fdae]{height:12lh}}@media (max-width: 500px){.hero-wrapper[data-v-a285fdae]{height:10lh}}@media (max-width: 400px){.hero-wrapper[data-v-a285fdae]{height:9lh}}.hero[data-v-a285fdae]{height:80%;width:unset;margin:auto;position:absolute;right:50%;bottom:0;transform:translate(calc(50% + var(--x-offset)));animation:bob-a285fdae 5s ease-in-out infinite}svg[data-v-a285fdae]{display:none}@keyframes bob-a285fdae{0%{transform:translate(calc(50% + var(--x-offset)),-10%)}50%{transform:translate(calc(50% + var(--x-offset)),10%)}to{transform:translate(calc(50% + var(--x-offset)),-10%)}}.VPLocalSearchBox[data-v-639d7ab9]{position:fixed;z-index:100;top:0;right:0;bottom:0;left:0;display:flex}.backdrop[data-v-639d7ab9]{position:absolute;top:0;right:0;bottom:0;left:0;background:var(--vp-backdrop-bg-color);transition:opacity .5s}.shell[data-v-639d7ab9]{position:relative;padding:12px;margin:64px auto;display:flex;flex-direction:column;gap:16px;background:var(--vp-local-search-bg);width:min(100vw - 60px,900px);height:min-content;max-height:min(100vh - 128px,900px);border-radius:6px}@media (max-width: 767px){.shell[data-v-639d7ab9]{margin:0;width:100vw;height:100vh;max-height:none;border-radius:0}}.search-bar[data-v-639d7ab9]{border:1px solid var(--vp-c-divider);border-radius:4px;display:flex;align-items:center;padding:0 12px;cursor:text}@media (max-width: 767px){.search-bar[data-v-639d7ab9]{padding:0 8px}}.search-bar[data-v-639d7ab9]:focus-within{border-color:var(--vp-c-brand-1)}.local-search-icon[data-v-639d7ab9]{display:block;font-size:18px}.navigate-icon[data-v-639d7ab9]{display:block;font-size:14px}.search-icon[data-v-639d7ab9]{margin:8px}@media (max-width: 767px){.search-icon[data-v-639d7ab9]{display:none}}.search-input[data-v-639d7ab9]{padding:6px 12px;font-size:inherit;width:100%}@media (max-width: 767px){.search-input[data-v-639d7ab9]{padding:6px 4px}}.search-actions[data-v-639d7ab9]{display:flex;gap:4px}@media (any-pointer: coarse){.search-actions[data-v-639d7ab9]{gap:8px}}@media (min-width: 769px){.search-actions.before[data-v-639d7ab9]{display:none}}.search-actions button[data-v-639d7ab9]{padding:8px}.search-actions button[data-v-639d7ab9]:not([disabled]):hover,.toggle-layout-button.detailed-list[data-v-639d7ab9]{color:var(--vp-c-brand-1)}.search-actions button.clear-button[data-v-639d7ab9]:disabled{opacity:.37}.search-keyboard-shortcuts[data-v-639d7ab9]{font-size:.8rem;opacity:75%;display:flex;flex-wrap:wrap;gap:16px;line-height:14px}.search-keyboard-shortcuts span[data-v-639d7ab9]{display:flex;align-items:center;gap:4px}@media (max-width: 767px){.search-keyboard-shortcuts[data-v-639d7ab9]{display:none}}.search-keyboard-shortcuts kbd[data-v-639d7ab9]{background:#8080801a;border-radius:4px;padding:3px 6px;min-width:24px;display:inline-block;text-align:center;vertical-align:middle;border:1px solid rgba(128,128,128,.15);box-shadow:0 2px 2px #0000001a}.results[data-v-639d7ab9]{display:flex;flex-direction:column;gap:6px;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain}.result[data-v-639d7ab9]{display:flex;align-items:center;gap:8px;border-radius:4px;transition:none;line-height:1rem;border:solid 2px var(--vp-local-search-result-border);outline:none}.result>div[data-v-639d7ab9]{margin:12px;width:100%;overflow:hidden}@media (max-width: 767px){.result>div[data-v-639d7ab9]{margin:8px}}.titles[data-v-639d7ab9]{display:flex;flex-wrap:wrap;gap:4px;position:relative;z-index:1001;padding:2px 0}.title[data-v-639d7ab9]{display:flex;align-items:center;gap:4px}.title.main[data-v-639d7ab9]{font-weight:500}.title-icon[data-v-639d7ab9]{opacity:.5;font-weight:500;color:var(--vp-c-brand-1)}.title svg[data-v-639d7ab9]{opacity:.5}.result.selected[data-v-639d7ab9]{--vp-local-search-result-bg: var(--vp-local-search-result-selected-bg);border-color:var(--vp-local-search-result-selected-border)}.excerpt-wrapper[data-v-639d7ab9]{position:relative}.excerpt[data-v-639d7ab9]{opacity:75%;pointer-events:none;max-height:140px;overflow:hidden;position:relative;opacity:.5;margin-top:4px}.result.selected .excerpt[data-v-639d7ab9]{opacity:1}.excerpt[data-v-639d7ab9] *{font-size:.8rem!important;line-height:130%!important}.titles[data-v-639d7ab9] mark,.excerpt[data-v-639d7ab9] mark{background-color:var(--vp-local-search-highlight-bg);color:var(--vp-local-search-highlight-text);border-radius:2px;padding:0 2px}.excerpt[data-v-639d7ab9] .vp-code-group .tabs{display:none}.excerpt[data-v-639d7ab9] .vp-code-group div[class*=language-]{border-radius:8px!important}.excerpt-gradient-bottom[data-v-639d7ab9]{position:absolute;bottom:-1px;left:0;width:100%;height:8px;background:linear-gradient(transparent,var(--vp-local-search-result-bg));z-index:1000}.excerpt-gradient-top[data-v-639d7ab9]{position:absolute;top:-1px;left:0;width:100%;height:8px;background:linear-gradient(var(--vp-local-search-result-bg),transparent);z-index:1000}.result.selected .titles[data-v-639d7ab9],.result.selected .title-icon[data-v-639d7ab9]{color:var(--vp-c-brand-1)!important}.no-results[data-v-639d7ab9]{font-size:.9rem;text-align:center;padding:12px}svg[data-v-639d7ab9]{flex:none} diff --git a/changelog/atom b/changelog/atom index c3fcdabba..04beaa514 100644 --- a/changelog/atom +++ b/changelog/atom @@ -2,7 +2,7 @@ https://www.thepaperpilot.org/changelog/ The Paper Pilot's Digital Garden Changelog - 2024-11-29T04:04:05.037Z + 2024-11-29T04:22:53.410Z https://github.com/jpmonette/feed The Paper Pilot @@ -791,6 +791,31 @@ a-plea-to-organize4 +++- +]]> + + + <![CDATA[ 8 files changed, 60 insertions(+), 25 deletions(-)]]> + https://code.incremental.social/thepaperpilot/pages/commit/2aaad90cb50d1f4b566a6062074c4abc02529445 + + 2024-11-12T14:35:33.000Z + + + + +Page +Changes + + + +anarchism62 +++++++++++++++++++++++------ +consensus-democracy2 +- +individualism6 +-- +my-political-beliefs2 +- +neoliberalism2 +- +{abolitionism => police-abolition}7 ++-- +social-constructs2 +- +technocracy2 +- + ]]> @@ -830,6 +855,24 @@ guide-to-incrementals/defining-the-genre59 ++++++++++++++--------- social-constructs2 +- +]]> + + + <![CDATA[ 1 file changed, 12 insertions(+), 10 deletions(-)]]> + https://code.incremental.social/thepaperpilot/pages/commit/3a2f58f8bb483acce423fb8904bd0603b0f080ed + + 2024-11-19T13:07:28.000Z + + + + +Page +Changes + + + +guide-to-incrementals/defining-the-genre22 ++++++++++++---------- + ]]> @@ -850,6 +893,26 @@ leftism96 +++++++++++++++++++++++++++++++++++++++++++ my-political-beliefs8 ++-- +]]> + + + <![CDATA[ 3 files changed, 4 insertions(+), 2 deletions(-)]]> + https://code.incremental.social/thepaperpilot/pages/commit/627e748c5d2efeef2372e6fadaff24003b572cb7 + + 2024-11-20T14:37:14.000Z + + + + +Page +Changes + + + +a-plea-to-organize2 ++ +anarchism2 +- +my-political-beliefs2 +- + ]]> @@ -871,6 +934,42 @@ my-political-beliefs2 +- my-political-journey4 ++-- +]]> + + + <![CDATA[ 19 files changed, 270 insertions(+), 35 deletions(-)]]> + https://code.incremental.social/thepaperpilot/pages/commit/557c67175ae0470a075bfcfc6f5fa325ea94615a + + 2024-11-24T07:36:02.000Z + + + + +Page +Changes + + + +anarchism2 +- +chromatic-lattice2 +- +commune2 +- +digital-gardens2 +- +digital-locality96 ++++++++++++++++++ +fedi-v22 +- +filter-bubbles112 +++++++++++++++++++++ +.../appeal-to-developers2 +- +guide-to-incrementals/appeal-to-players2 +- +guide-to-incrementals/defining-the-genre2 +- +.../navigating-criticism2 +- +guide-to-incrementals/what-is-content2 +- +leftism2 +- +objectivity10 +- +social-media22 ++-- +the-indieweb/amplification2 +- +the-indieweb/signature-blocks2 +- +the-small-web2 +- +video-essays37 +++++++ + ]]> @@ -927,11 +1026,11 @@ ]]> - <![CDATA[ 1 file changed, 12 insertions(+), 10 deletions(-)]]> - https://code.incremental.social/thepaperpilot/pages/commit/3a2f58f8bb483acce423fb8904bd0603b0f080ed - - 2024-11-19T13:07:28.000Z - + <![CDATA[ 1 file changed, 3 insertions(+), 3 deletions(-)]]> + https://code.incremental.social/thepaperpilot/pages/commit/50fc43997fde6ba5648dcf9bb2ad34df5e125be5 + + 2024-11-29T04:20:23.000Z + @@ -940,152 +1039,7 @@ -guide-to-incrementals/defining-the-genre22 ++++++++++++---------- - -]]> - - - <![CDATA[ 19 files changed, 270 insertions(+), 35 deletions(-)]]> - https://code.incremental.social/thepaperpilot/pages/commit/557c67175ae0470a075bfcfc6f5fa325ea94615a - - 2024-11-24T07:36:02.000Z - - - - -Page -Changes - - - -anarchism2 +- -chromatic-lattice2 +- -commune2 +- -digital-gardens2 +- -digital-locality96 ++++++++++++++++++ -fedi-v22 +- -filter-bubbles112 +++++++++++++++++++++ -.../appeal-to-developers2 +- -guide-to-incrementals/appeal-to-players2 +- -guide-to-incrementals/defining-the-genre2 +- -.../navigating-criticism2 +- -guide-to-incrementals/what-is-content2 +- -leftism2 +- -objectivity10 +- -social-media22 ++-- -the-indieweb/amplification2 +- -the-indieweb/signature-blocks2 +- -the-small-web2 +- -video-essays37 +++++++ - -]]> - - - <![CDATA[ 8 files changed, 60 insertions(+), 25 deletions(-)]]> - https://code.incremental.social/thepaperpilot/pages/commit/2aaad90cb50d1f4b566a6062074c4abc02529445 - - 2024-11-12T14:35:33.000Z - - - - -Page -Changes - - - -anarchism62 +++++++++++++++++++++++------ -consensus-democracy2 +- -individualism6 +-- -my-political-beliefs2 +- -neoliberalism2 +- -{abolitionism => police-abolition}7 ++-- -social-constructs2 +- -technocracy2 +- - -]]> - - - <![CDATA[ 3 files changed, 4 insertions(+), 2 deletions(-)]]> - https://code.incremental.social/thepaperpilot/pages/commit/627e748c5d2efeef2372e6fadaff24003b572cb7 - - 2024-11-20T14:37:14.000Z - - - - -Page -Changes - - - -a-plea-to-organize2 ++ -anarchism2 +- -my-political-beliefs2 +- - -]]> - - - <![CDATA[ 47 files changed, 1226 insertions(+)]]> - https://code.incremental.social/thepaperpilot/pages/commit/fe175090d3fc0cfa81754ec5b19a184005e31d8c - - 2024-06-04T03:59:20.000Z - - - - -Page -Changes - - - -activitypub13 ++ -advent-incremental21 +++ -atproto18 +++ -babble-buds22 ++++ -capture-the-citadel15 +++ -chat-glue12 ++ -chronological21 +++ -cinny10 ++ -commune33 +++++ -decentralized28 ++++ -dice-armor55 ++++++++ -digital-gardens20 +++ -federated-identity23 ++++ -fedi-v295 ++++++++++++++ -fediverse21 +++ -forgejo10 ++ -freeform-vs-chronological-dichotomy10 ++ -freeform17 +++ -game-dev-tree17 +++ -garden-rss22 ++++ -.../appeal-to-developers30 +++++ -guide-to-incrementals/appeal-to-players60 +++++++++ -guide-to-incrementals/defining-the-genre141 +++++++++++++++++++++ -guide-to-incrementals27 ++++ -.../navigating-criticism26 ++++ -guide-to-incrementals/what-is-content52 ++++++++ -incremental-social16 +++ -kronos18 +++ -logseq10 ++ -matrix10 ++ -mbin12 ++ -my-personal-website10 ++ -my-projects27 ++++ -nostr13 ++ -open-source12 ++ -opti-speech37 ++++++ -planar-pioneers15 +++ -profectus24 ++++ -social-media25 ++++ -synapse10 ++ -the-cozy-web16 +++ -the-small-web58 +++++++++ -this-knowledge-hub22 ++++ -v-ecs25 ++++ -vitepress10 ++ -webrings25 ++++ -weird12 ++ +no-politics-rules6 +++--- ]]> @@ -1151,6 +1105,70 @@ webrings2 ++ weird2 ++ +]]> + + + <![CDATA[ 47 files changed, 1226 insertions(+)]]> + https://code.incremental.social/thepaperpilot/pages/commit/fe175090d3fc0cfa81754ec5b19a184005e31d8c + + 2024-06-04T03:59:20.000Z + + + + +Page +Changes + + + +activitypub13 ++ +advent-incremental21 +++ +atproto18 +++ +babble-buds22 ++++ +capture-the-citadel15 +++ +chat-glue12 ++ +chronological21 +++ +cinny10 ++ +commune33 +++++ +decentralized28 ++++ +dice-armor55 ++++++++ +digital-gardens20 +++ +federated-identity23 ++++ +fedi-v295 ++++++++++++++ +fediverse21 +++ +forgejo10 ++ +freeform-vs-chronological-dichotomy10 ++ +freeform17 +++ +game-dev-tree17 +++ +garden-rss22 ++++ +.../appeal-to-developers30 +++++ +guide-to-incrementals/appeal-to-players60 +++++++++ +guide-to-incrementals/defining-the-genre141 +++++++++++++++++++++ +guide-to-incrementals27 ++++ +.../navigating-criticism26 ++++ +guide-to-incrementals/what-is-content52 ++++++++ +incremental-social16 +++ +kronos18 +++ +logseq10 ++ +matrix10 ++ +mbin12 ++ +my-personal-website10 ++ +my-projects27 ++++ +nostr13 ++ +open-source12 ++ +opti-speech37 ++++++ +planar-pioneers15 +++ +profectus24 ++++ +social-media25 ++++ +synapse10 ++ +the-cozy-web16 +++ +the-small-web58 +++++++++ +this-knowledge-hub22 ++++ +v-ecs25 ++++ +vitepress10 ++ +webrings25 ++++ +weird12 ++ + ]]> \ No newline at end of file diff --git a/changelog/index.html b/changelog/index.html index 58091e5bc..d46ee0fbb 100644 --- a/changelog/index.html +++ b/changelog/index.html @@ -6,13 +6,13 @@ Garden Changelog | The Paper Pilot - + - + - - + + @@ -50,7 +50,8 @@ -
Skip to content

Garden Changelog

This feed starts when I formatted the site to be a Digital Garden. If you'd like to look further into this site's history, check here!

36 files changed, 517 insertions(+), 200 deletions(-)

Pushed on
Skip to content

Garden Changelog

This feed starts when I formatted the site to be a Digital Garden. If you'd like to look further into this site's history, check here!

36 files changed, 517 insertions(+), 200 deletions(-)

Pushed on
PageChanges
activitypub22 -----------
anarchism2 +-
atproto13 ++-----
chromatic-lattice10 ++++-
commune4 +-
consensus-democracy6 +--
debate64 ++++++++++++++++++++++++++++++
decentralized-identity45 ++++++++++++++++++++++
decentralized-moderation51 ++++++++++++++++++++++++
decentralized-social-media21 ++++++++++
decentralized12 +++---
digital-gardens2 +-
digital-locality77 ++++++++++++++++++-------------------
enshittification20 ++++++++++
everything-is-political53 +++++++++++++++++++++++++
federated-identity33 ----------------
fedi-v230 +++------------
fediverse16 +++-----
filter-bubbles10 ++---
incremental-social6 +--
leftism2 +-
local-communities2 +-
moderation36 +++++++++++++++++
my-personal-website2 +-
no-politics-rules74 +++++++++++++++++++++++++++++++++++
nostr8 ++--
objectivity2 +-
police-abolition8 ++--
social-media6 +--
the-small-web6 +--
this-knowledge-hub19 +++------
trans-athletes-in-sports2 +
video-essays6 ++-
virality43 +++++++++++++++++++++
vitepress2 +-
weird2 +-

19 files changed, 270 insertions(+), 35 deletions(-)

47 files changed, 124 insertions(+), 13 deletions(-)

47 files changed, 1226 insertions(+)

- +">2024-06-03
PageChanges
activitypub13 ++
advent-incremental21 +++
atproto18 +++
babble-buds22 ++++
capture-the-citadel15 +++
chat-glue12 ++
chronological21 +++
cinny10 ++
commune33 +++++
decentralized28 ++++
dice-armor55 ++++++++
digital-gardens20 +++
federated-identity23 ++++
fedi-v295 ++++++++++++++
fediverse21 +++
forgejo10 ++
freeform-vs-chronological-dichotomy10 ++
freeform17 +++
game-dev-tree17 +++
garden-rss22 ++++
.../appeal-to-developers30 +++++
guide-to-incrementals/appeal-to-players60 +++++++++
guide-to-incrementals/defining-the-genre141 +++++++++++++++++++++
guide-to-incrementals27 ++++
.../navigating-criticism26 ++++
guide-to-incrementals/what-is-content52 ++++++++
incremental-social16 +++
kronos18 +++
logseq10 ++
matrix10 ++
mbin12 ++
my-personal-website10 ++
my-projects27 ++++
nostr13 ++
open-source12 ++
opti-speech37 ++++++
planar-pioneers15 +++
profectus24 ++++
social-media25 ++++
synapse10 ++
the-cozy-web16 +++
the-small-web58 +++++++++
this-knowledge-hub22 ++++
v-ecs25 ++++
vitepress10 ++
webrings25 ++++
weird12 ++
+ \ No newline at end of file diff --git a/changelog/json b/changelog/json index e8f4ac2e4..7db26d746 100644 --- a/changelog/json +++ b/changelog/json @@ -241,6 +241,14 @@ "summary": " 1 file changed, 3 insertions(+), 1 deletion(-)", "date_modified": "2024-11-12T02:26:46.000Z" }, + { + "id": "https://code.incremental.social/thepaperpilot/pages/commit/2aaad90cb50d1f4b566a6062074c4abc02529445", + "content_html": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
PageChanges
anarchism62 +++++++++++++++++++++++------
consensus-democracy2 +-
individualism6 +--
my-political-beliefs2 +-
neoliberalism2 +-
police-abolition}\">{abolitionism => police-abolition}7 ++--
social-constructs2 +-
technocracy2 +-
", + "url": "https://code.incremental.social/thepaperpilot/pages/commit/2aaad90cb50d1f4b566a6062074c4abc02529445", + "title": " 8 files changed, 60 insertions(+), 25 deletions(-)", + "summary": " 8 files changed, 60 insertions(+), 25 deletions(-)", + "date_modified": "2024-11-12T14:35:33.000Z" + }, { "id": "https://code.incremental.social/thepaperpilot/pages/commit/a894efb9b6b192f7fe057be5879f0687bda6cde7", "content_html": "\n\n\n\n\n\n\n\n\n\n\n\n
PageChanges
a-plea-to-organize4 ++--
anarchism20 +++++++++++---------
police-abolition6 +++++-
", @@ -257,30 +265,6 @@ "summary": " 2 files changed, 37 insertions(+), 24 deletions(-)", "date_modified": "2024-11-18T12:09:56.000Z" }, - { - "id": "https://code.incremental.social/thepaperpilot/pages/commit/cdc332bb6a432a45a3665c92165952266d247f07", - "content_html": "\n\n\n\n\n\n\n\n\n\n\n\n
PageChanges
anarchism8 ++--
leftism96 +++++++++++++++++++++++++++++++++++++++++++
my-political-beliefs8 ++--
", - "url": "https://code.incremental.social/thepaperpilot/pages/commit/cdc332bb6a432a45a3665c92165952266d247f07", - "title": " 3 files changed, 106 insertions(+), 6 deletions(-)", - "summary": " 3 files changed, 106 insertions(+), 6 deletions(-)", - "date_modified": "2024-11-20T14:34:13.000Z" - }, - { - "id": "https://code.incremental.social/thepaperpilot/pages/commit/46548f5078c1ec182f8171a1111c7d2efdcdd707", - "content_html": "\n\n\n\n\n\n\n\n\n\n\n\n\n
PageChanges
imperialism46 +++++++++++++++++++++++++++++++++++++++++++
leftism10 ++++++----
my-political-beliefs2 +-
my-political-journey4 ++--
", - "url": "https://code.incremental.social/thepaperpilot/pages/commit/46548f5078c1ec182f8171a1111c7d2efdcdd707", - "title": " 4 files changed, 55 insertions(+), 7 deletions(-)", - "summary": " 4 files changed, 55 insertions(+), 7 deletions(-)", - "date_modified": "2024-11-21T00:06:07.000Z" - }, - { - "id": "https://code.incremental.social/thepaperpilot/pages/commit/9aa6bf46bfd132527bed478007a37223f4f29de6", - "content_html": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
PageChanges
activitypub22 -----------
anarchism2 +-
atproto13 ++-----
chromatic-lattice10 ++++-
commune4 +-
consensus-democracy6 +--
debate64 ++++++++++++++++++++++++++++++
decentralized-identity45 ++++++++++++++++++++++
decentralized-moderation51 ++++++++++++++++++++++++
decentralized-social-media21 ++++++++++
decentralized12 +++---
digital-gardens2 +-
digital-locality77 ++++++++++++++++++-------------------
enshittification20 ++++++++++
everything-is-political53 +++++++++++++++++++++++++
federated-identity33 ----------------
fedi-v230 +++------------
fediverse16 +++-----
filter-bubbles10 ++---
incremental-social6 +--
leftism2 +-
local-communities2 +-
moderation36 +++++++++++++++++
my-personal-website2 +-
no-politics-rules74 +++++++++++++++++++++++++++++++++++
nostr8 ++--
objectivity2 +-
police-abolition8 ++--
social-media6 +--
the-small-web6 +--
this-knowledge-hub19 +++------
trans-athletes-in-sports2 +
video-essays6 ++-
virality43 +++++++++++++++++++++
vitepress2 +-
weird2 +-
", - "url": "https://code.incremental.social/thepaperpilot/pages/commit/9aa6bf46bfd132527bed478007a37223f4f29de6", - "title": " 36 files changed, 517 insertions(+), 200 deletions(-)", - "summary": " 36 files changed, 517 insertions(+), 200 deletions(-)", - "date_modified": "2024-11-29T04:01:32.000Z" - }, { "id": "https://code.incremental.social/thepaperpilot/pages/commit/3a2f58f8bb483acce423fb8904bd0603b0f080ed", "content_html": "\n\n\n\n\n\n\n\n\n\n
PageChanges
guide-to-incrementals/defining-the-genre22 ++++++++++++----------
", @@ -290,20 +274,12 @@ "date_modified": "2024-11-19T13:07:28.000Z" }, { - "id": "https://code.incremental.social/thepaperpilot/pages/commit/557c67175ae0470a075bfcfc6f5fa325ea94615a", - "content_html": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
PageChanges
anarchism2 +-
chromatic-lattice2 +-
commune2 +-
digital-gardens2 +-
digital-locality96 ++++++++++++++++++
fedi-v22 +-
filter-bubbles112 +++++++++++++++++++++
.../appeal-to-developers2 +-
guide-to-incrementals/appeal-to-players2 +-
guide-to-incrementals/defining-the-genre2 +-
.../navigating-criticism2 +-
guide-to-incrementals/what-is-content2 +-
leftism2 +-
objectivity10 +-
social-media22 ++--
the-indieweb/amplification2 +-
the-indieweb/signature-blocks2 +-
the-small-web2 +-
video-essays37 +++++++
", - "url": "https://code.incremental.social/thepaperpilot/pages/commit/557c67175ae0470a075bfcfc6f5fa325ea94615a", - "title": " 19 files changed, 270 insertions(+), 35 deletions(-)", - "summary": " 19 files changed, 270 insertions(+), 35 deletions(-)", - "date_modified": "2024-11-24T07:36:02.000Z" - }, - { - "id": "https://code.incremental.social/thepaperpilot/pages/commit/2aaad90cb50d1f4b566a6062074c4abc02529445", - "content_html": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
PageChanges
anarchism62 +++++++++++++++++++++++------
consensus-democracy2 +-
individualism6 +--
my-political-beliefs2 +-
neoliberalism2 +-
police-abolition}\">{abolitionism => police-abolition}7 ++--
social-constructs2 +-
technocracy2 +-
", - "url": "https://code.incremental.social/thepaperpilot/pages/commit/2aaad90cb50d1f4b566a6062074c4abc02529445", - "title": " 8 files changed, 60 insertions(+), 25 deletions(-)", - "summary": " 8 files changed, 60 insertions(+), 25 deletions(-)", - "date_modified": "2024-11-12T14:35:33.000Z" + "id": "https://code.incremental.social/thepaperpilot/pages/commit/cdc332bb6a432a45a3665c92165952266d247f07", + "content_html": "\n\n\n\n\n\n\n\n\n\n\n\n
PageChanges
anarchism8 ++--
leftism96 +++++++++++++++++++++++++++++++++++++++++++
my-political-beliefs8 ++--
", + "url": "https://code.incremental.social/thepaperpilot/pages/commit/cdc332bb6a432a45a3665c92165952266d247f07", + "title": " 3 files changed, 106 insertions(+), 6 deletions(-)", + "summary": " 3 files changed, 106 insertions(+), 6 deletions(-)", + "date_modified": "2024-11-20T14:34:13.000Z" }, { "id": "https://code.incremental.social/thepaperpilot/pages/commit/627e748c5d2efeef2372e6fadaff24003b572cb7", @@ -314,12 +290,36 @@ "date_modified": "2024-11-20T14:37:14.000Z" }, { - "id": "https://code.incremental.social/thepaperpilot/pages/commit/fe175090d3fc0cfa81754ec5b19a184005e31d8c", - "content_html": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
PageChanges
activitypub13 ++
advent-incremental21 +++
atproto18 +++
babble-buds22 ++++
capture-the-citadel15 +++
chat-glue12 ++
chronological21 +++
cinny10 ++
commune33 +++++
decentralized28 ++++
dice-armor55 ++++++++
digital-gardens20 +++
federated-identity23 ++++
fedi-v295 ++++++++++++++
fediverse21 +++
forgejo10 ++
freeform-vs-chronological-dichotomy10 ++
freeform17 +++
game-dev-tree17 +++
garden-rss22 ++++
.../appeal-to-developers30 +++++
guide-to-incrementals/appeal-to-players60 +++++++++
guide-to-incrementals/defining-the-genre141 +++++++++++++++++++++
guide-to-incrementals27 ++++
.../navigating-criticism26 ++++
guide-to-incrementals/what-is-content52 ++++++++
incremental-social16 +++
kronos18 +++
logseq10 ++
matrix10 ++
mbin12 ++
my-personal-website10 ++
my-projects27 ++++
nostr13 ++
open-source12 ++
opti-speech37 ++++++
planar-pioneers15 +++
profectus24 ++++
social-media25 ++++
synapse10 ++
the-cozy-web16 +++
the-small-web58 +++++++++
this-knowledge-hub22 ++++
v-ecs25 ++++
vitepress10 ++
webrings25 ++++
weird12 ++
", - "url": "https://code.incremental.social/thepaperpilot/pages/commit/fe175090d3fc0cfa81754ec5b19a184005e31d8c", - "title": " 47 files changed, 1226 insertions(+)", - "summary": " 47 files changed, 1226 insertions(+)", - "date_modified": "2024-06-04T03:59:20.000Z" + "id": "https://code.incremental.social/thepaperpilot/pages/commit/46548f5078c1ec182f8171a1111c7d2efdcdd707", + "content_html": "\n\n\n\n\n\n\n\n\n\n\n\n\n
PageChanges
imperialism46 +++++++++++++++++++++++++++++++++++++++++++
leftism10 ++++++----
my-political-beliefs2 +-
my-political-journey4 ++--
", + "url": "https://code.incremental.social/thepaperpilot/pages/commit/46548f5078c1ec182f8171a1111c7d2efdcdd707", + "title": " 4 files changed, 55 insertions(+), 7 deletions(-)", + "summary": " 4 files changed, 55 insertions(+), 7 deletions(-)", + "date_modified": "2024-11-21T00:06:07.000Z" + }, + { + "id": "https://code.incremental.social/thepaperpilot/pages/commit/557c67175ae0470a075bfcfc6f5fa325ea94615a", + "content_html": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
PageChanges
anarchism2 +-
chromatic-lattice2 +-
commune2 +-
digital-gardens2 +-
digital-locality96 ++++++++++++++++++
fedi-v22 +-
filter-bubbles112 +++++++++++++++++++++
.../appeal-to-developers2 +-
guide-to-incrementals/appeal-to-players2 +-
guide-to-incrementals/defining-the-genre2 +-
.../navigating-criticism2 +-
guide-to-incrementals/what-is-content2 +-
leftism2 +-
objectivity10 +-
social-media22 ++--
the-indieweb/amplification2 +-
the-indieweb/signature-blocks2 +-
the-small-web2 +-
video-essays37 +++++++
", + "url": "https://code.incremental.social/thepaperpilot/pages/commit/557c67175ae0470a075bfcfc6f5fa325ea94615a", + "title": " 19 files changed, 270 insertions(+), 35 deletions(-)", + "summary": " 19 files changed, 270 insertions(+), 35 deletions(-)", + "date_modified": "2024-11-24T07:36:02.000Z" + }, + { + "id": "https://code.incremental.social/thepaperpilot/pages/commit/9aa6bf46bfd132527bed478007a37223f4f29de6", + "content_html": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
PageChanges
activitypub22 -----------
anarchism2 +-
atproto13 ++-----
chromatic-lattice10 ++++-
commune4 +-
consensus-democracy6 +--
debate64 ++++++++++++++++++++++++++++++
decentralized-identity45 ++++++++++++++++++++++
decentralized-moderation51 ++++++++++++++++++++++++
decentralized-social-media21 ++++++++++
decentralized12 +++---
digital-gardens2 +-
digital-locality77 ++++++++++++++++++-------------------
enshittification20 ++++++++++
everything-is-political53 +++++++++++++++++++++++++
federated-identity33 ----------------
fedi-v230 +++------------
fediverse16 +++-----
filter-bubbles10 ++---
incremental-social6 +--
leftism2 +-
local-communities2 +-
moderation36 +++++++++++++++++
my-personal-website2 +-
no-politics-rules74 +++++++++++++++++++++++++++++++++++
nostr8 ++--
objectivity2 +-
police-abolition8 ++--
social-media6 +--
the-small-web6 +--
this-knowledge-hub19 +++------
trans-athletes-in-sports2 +
video-essays6 ++-
virality43 +++++++++++++++++++++
vitepress2 +-
weird2 +-
", + "url": "https://code.incremental.social/thepaperpilot/pages/commit/9aa6bf46bfd132527bed478007a37223f4f29de6", + "title": " 36 files changed, 517 insertions(+), 200 deletions(-)", + "summary": " 36 files changed, 517 insertions(+), 200 deletions(-)", + "date_modified": "2024-11-29T04:01:32.000Z" + }, + { + "id": "https://code.incremental.social/thepaperpilot/pages/commit/50fc43997fde6ba5648dcf9bb2ad34df5e125be5", + "content_html": "\n\n\n\n\n\n\n\n\n\n
PageChanges
no-politics-rules6 +++---
", + "url": "https://code.incremental.social/thepaperpilot/pages/commit/50fc43997fde6ba5648dcf9bb2ad34df5e125be5", + "title": " 1 file changed, 3 insertions(+), 3 deletions(-)", + "summary": " 1 file changed, 3 insertions(+), 3 deletions(-)", + "date_modified": "2024-11-29T04:20:23.000Z" }, { "id": "https://code.incremental.social/thepaperpilot/pages/commit/91e757f7ccbeb570d900aaa5b49e6e4874d19b2f", @@ -328,6 +328,14 @@ "title": " 47 files changed, 124 insertions(+), 13 deletions(-)", "summary": " 47 files changed, 124 insertions(+), 13 deletions(-)", "date_modified": "2024-06-06T04:25:48.000Z" + }, + { + "id": "https://code.incremental.social/thepaperpilot/pages/commit/fe175090d3fc0cfa81754ec5b19a184005e31d8c", + "content_html": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
PageChanges
activitypub13 ++
advent-incremental21 +++
atproto18 +++
babble-buds22 ++++
capture-the-citadel15 +++
chat-glue12 ++
chronological21 +++
cinny10 ++
commune33 +++++
decentralized28 ++++
dice-armor55 ++++++++
digital-gardens20 +++
federated-identity23 ++++
fedi-v295 ++++++++++++++
fediverse21 +++
forgejo10 ++
freeform-vs-chronological-dichotomy10 ++
freeform17 +++
game-dev-tree17 +++
garden-rss22 ++++
.../appeal-to-developers30 +++++
guide-to-incrementals/appeal-to-players60 +++++++++
guide-to-incrementals/defining-the-genre141 +++++++++++++++++++++
guide-to-incrementals27 ++++
.../navigating-criticism26 ++++
guide-to-incrementals/what-is-content52 ++++++++
incremental-social16 +++
kronos18 +++
logseq10 ++
matrix10 ++
mbin12 ++
my-personal-website10 ++
my-projects27 ++++
nostr13 ++
open-source12 ++
opti-speech37 ++++++
planar-pioneers15 +++
profectus24 ++++
social-media25 ++++
synapse10 ++
the-cozy-web16 +++
the-small-web58 +++++++++
this-knowledge-hub22 ++++
v-ecs25 ++++
vitepress10 ++
webrings25 ++++
weird12 ++
", + "url": "https://code.incremental.social/thepaperpilot/pages/commit/fe175090d3fc0cfa81754ec5b19a184005e31d8c", + "title": " 47 files changed, 1226 insertions(+)", + "summary": " 47 files changed, 1226 insertions(+)", + "date_modified": "2024-06-04T03:59:20.000Z" } ] } \ No newline at end of file diff --git a/changelog/rss b/changelog/rss index ed86bf10a..50bb684dd 100644 --- a/changelog/rss +++ b/changelog/rss @@ -4,7 +4,7 @@ The Paper Pilot's Digital Garden Changelog https://www.thepaperpilot.org/changelog/ A feed of updates made to my digital garden! - Fri, 29 Nov 2024 04:04:05 GMT + Fri, 29 Nov 2024 04:22:53 GMT https://validator.w3.org/feed/docs/rss2.html https://github.com/jpmonette/feed en @@ -788,6 +788,31 @@ a-plea-to-organize4 +++- +]]> + + + <![CDATA[ 8 files changed, 60 insertions(+), 25 deletions(-)]]> + https://code.incremental.social/thepaperpilot/pages/commit/2aaad90cb50d1f4b566a6062074c4abc02529445 + https://code.incremental.social/thepaperpilot/pages/commit/2aaad90cb50d1f4b566a6062074c4abc02529445 + Tue, 12 Nov 2024 14:35:33 GMT + + + + +Page +Changes + + + +anarchism62 +++++++++++++++++++++++------ +consensus-democracy2 +- +individualism6 +-- +my-political-beliefs2 +- +neoliberalism2 +- +{abolitionism => police-abolition}7 ++-- +social-constructs2 +- +technocracy2 +- + ]]> @@ -827,6 +852,24 @@ guide-to-incrementals/defining-the-genre59 ++++++++++++++--------- social-constructs2 +- +]]> + + + <![CDATA[ 1 file changed, 12 insertions(+), 10 deletions(-)]]> + https://code.incremental.social/thepaperpilot/pages/commit/3a2f58f8bb483acce423fb8904bd0603b0f080ed + https://code.incremental.social/thepaperpilot/pages/commit/3a2f58f8bb483acce423fb8904bd0603b0f080ed + Tue, 19 Nov 2024 13:07:28 GMT + + + + +Page +Changes + + + +guide-to-incrementals/defining-the-genre22 ++++++++++++---------- + ]]> @@ -847,6 +890,26 @@ leftism96 +++++++++++++++++++++++++++++++++++++++++++ my-political-beliefs8 ++-- +]]> + + + <![CDATA[ 3 files changed, 4 insertions(+), 2 deletions(-)]]> + https://code.incremental.social/thepaperpilot/pages/commit/627e748c5d2efeef2372e6fadaff24003b572cb7 + https://code.incremental.social/thepaperpilot/pages/commit/627e748c5d2efeef2372e6fadaff24003b572cb7 + Wed, 20 Nov 2024 14:37:14 GMT + + + + +Page +Changes + + + +a-plea-to-organize2 ++ +anarchism2 +- +my-political-beliefs2 +- + ]]> @@ -868,6 +931,42 @@ my-political-beliefs2 +- my-political-journey4 ++-- +]]> + + + <![CDATA[ 19 files changed, 270 insertions(+), 35 deletions(-)]]> + https://code.incremental.social/thepaperpilot/pages/commit/557c67175ae0470a075bfcfc6f5fa325ea94615a + https://code.incremental.social/thepaperpilot/pages/commit/557c67175ae0470a075bfcfc6f5fa325ea94615a + Sun, 24 Nov 2024 07:36:02 GMT + + + + +Page +Changes + + + +anarchism2 +- +chromatic-lattice2 +- +commune2 +- +digital-gardens2 +- +digital-locality96 ++++++++++++++++++ +fedi-v22 +- +filter-bubbles112 +++++++++++++++++++++ +.../appeal-to-developers2 +- +guide-to-incrementals/appeal-to-players2 +- +guide-to-incrementals/defining-the-genre2 +- +.../navigating-criticism2 +- +guide-to-incrementals/what-is-content2 +- +leftism2 +- +objectivity10 +- +social-media22 ++-- +the-indieweb/amplification2 +- +the-indieweb/signature-blocks2 +- +the-small-web2 +- +video-essays37 +++++++ + ]]> @@ -924,11 +1023,11 @@ ]]> - <![CDATA[ 1 file changed, 12 insertions(+), 10 deletions(-)]]> - https://code.incremental.social/thepaperpilot/pages/commit/3a2f58f8bb483acce423fb8904bd0603b0f080ed - https://code.incremental.social/thepaperpilot/pages/commit/3a2f58f8bb483acce423fb8904bd0603b0f080ed - Tue, 19 Nov 2024 13:07:28 GMT - + <![CDATA[ 1 file changed, 3 insertions(+), 3 deletions(-)]]> + https://code.incremental.social/thepaperpilot/pages/commit/50fc43997fde6ba5648dcf9bb2ad34df5e125be5 + https://code.incremental.social/thepaperpilot/pages/commit/50fc43997fde6ba5648dcf9bb2ad34df5e125be5 + Fri, 29 Nov 2024 04:20:23 GMT + @@ -937,152 +1036,7 @@ -guide-to-incrementals/defining-the-genre22 ++++++++++++---------- - -]]> - - - <![CDATA[ 19 files changed, 270 insertions(+), 35 deletions(-)]]> - https://code.incremental.social/thepaperpilot/pages/commit/557c67175ae0470a075bfcfc6f5fa325ea94615a - https://code.incremental.social/thepaperpilot/pages/commit/557c67175ae0470a075bfcfc6f5fa325ea94615a - Sun, 24 Nov 2024 07:36:02 GMT - - - - -Page -Changes - - - -anarchism2 +- -chromatic-lattice2 +- -commune2 +- -digital-gardens2 +- -digital-locality96 ++++++++++++++++++ -fedi-v22 +- -filter-bubbles112 +++++++++++++++++++++ -.../appeal-to-developers2 +- -guide-to-incrementals/appeal-to-players2 +- -guide-to-incrementals/defining-the-genre2 +- -.../navigating-criticism2 +- -guide-to-incrementals/what-is-content2 +- -leftism2 +- -objectivity10 +- -social-media22 ++-- -the-indieweb/amplification2 +- -the-indieweb/signature-blocks2 +- -the-small-web2 +- -video-essays37 +++++++ - -]]> - - - <![CDATA[ 8 files changed, 60 insertions(+), 25 deletions(-)]]> - https://code.incremental.social/thepaperpilot/pages/commit/2aaad90cb50d1f4b566a6062074c4abc02529445 - https://code.incremental.social/thepaperpilot/pages/commit/2aaad90cb50d1f4b566a6062074c4abc02529445 - Tue, 12 Nov 2024 14:35:33 GMT - - - - -Page -Changes - - - -anarchism62 +++++++++++++++++++++++------ -consensus-democracy2 +- -individualism6 +-- -my-political-beliefs2 +- -neoliberalism2 +- -{abolitionism => police-abolition}7 ++-- -social-constructs2 +- -technocracy2 +- - -]]> - - - <![CDATA[ 3 files changed, 4 insertions(+), 2 deletions(-)]]> - https://code.incremental.social/thepaperpilot/pages/commit/627e748c5d2efeef2372e6fadaff24003b572cb7 - https://code.incremental.social/thepaperpilot/pages/commit/627e748c5d2efeef2372e6fadaff24003b572cb7 - Wed, 20 Nov 2024 14:37:14 GMT - - - - -Page -Changes - - - -a-plea-to-organize2 ++ -anarchism2 +- -my-political-beliefs2 +- - -]]> - - - <![CDATA[ 47 files changed, 1226 insertions(+)]]> - https://code.incremental.social/thepaperpilot/pages/commit/fe175090d3fc0cfa81754ec5b19a184005e31d8c - https://code.incremental.social/thepaperpilot/pages/commit/fe175090d3fc0cfa81754ec5b19a184005e31d8c - Tue, 04 Jun 2024 03:59:20 GMT - - - - -Page -Changes - - - -activitypub13 ++ -advent-incremental21 +++ -atproto18 +++ -babble-buds22 ++++ -capture-the-citadel15 +++ -chat-glue12 ++ -chronological21 +++ -cinny10 ++ -commune33 +++++ -decentralized28 ++++ -dice-armor55 ++++++++ -digital-gardens20 +++ -federated-identity23 ++++ -fedi-v295 ++++++++++++++ -fediverse21 +++ -forgejo10 ++ -freeform-vs-chronological-dichotomy10 ++ -freeform17 +++ -game-dev-tree17 +++ -garden-rss22 ++++ -.../appeal-to-developers30 +++++ -guide-to-incrementals/appeal-to-players60 +++++++++ -guide-to-incrementals/defining-the-genre141 +++++++++++++++++++++ -guide-to-incrementals27 ++++ -.../navigating-criticism26 ++++ -guide-to-incrementals/what-is-content52 ++++++++ -incremental-social16 +++ -kronos18 +++ -logseq10 ++ -matrix10 ++ -mbin12 ++ -my-personal-website10 ++ -my-projects27 ++++ -nostr13 ++ -open-source12 ++ -opti-speech37 ++++++ -planar-pioneers15 +++ -profectus24 ++++ -social-media25 ++++ -synapse10 ++ -the-cozy-web16 +++ -the-small-web58 +++++++++ -this-knowledge-hub22 ++++ -v-ecs25 ++++ -vitepress10 ++ -webrings25 ++++ -weird12 ++ +no-politics-rules6 +++--- ]]> @@ -1148,6 +1102,70 @@ webrings2 ++ weird2 ++ +]]> + + + <![CDATA[ 47 files changed, 1226 insertions(+)]]> + https://code.incremental.social/thepaperpilot/pages/commit/fe175090d3fc0cfa81754ec5b19a184005e31d8c + https://code.incremental.social/thepaperpilot/pages/commit/fe175090d3fc0cfa81754ec5b19a184005e31d8c + Tue, 04 Jun 2024 03:59:20 GMT + + + + +Page +Changes + + + +activitypub13 ++ +advent-incremental21 +++ +atproto18 +++ +babble-buds22 ++++ +capture-the-citadel15 +++ +chat-glue12 ++ +chronological21 +++ +cinny10 ++ +commune33 +++++ +decentralized28 ++++ +dice-armor55 ++++++++ +digital-gardens20 +++ +federated-identity23 ++++ +fedi-v295 ++++++++++++++ +fediverse21 +++ +forgejo10 ++ +freeform-vs-chronological-dichotomy10 ++ +freeform17 +++ +game-dev-tree17 +++ +garden-rss22 ++++ +.../appeal-to-developers30 +++++ +guide-to-incrementals/appeal-to-players60 +++++++++ +guide-to-incrementals/defining-the-genre141 +++++++++++++++++++++ +guide-to-incrementals27 ++++ +.../navigating-criticism26 ++++ +guide-to-incrementals/what-is-content52 ++++++++ +incremental-social16 +++ +kronos18 +++ +logseq10 ++ +matrix10 ++ +mbin12 ++ +my-personal-website10 ++ +my-projects27 ++++ +nostr13 ++ +open-source12 ++ +opti-speech37 ++++++ +planar-pioneers15 +++ +profectus24 ++++ +social-media25 ++++ +synapse10 ++ +the-cozy-web16 +++ +the-small-web58 +++++++++ +this-knowledge-hub22 ++++ +v-ecs25 ++++ +vitepress10 ++ +webrings25 ++++ +weird12 ++ + ]]> diff --git a/garden/a-plea-to-organize/index.html b/garden/a-plea-to-organize/index.html index 6972a9f2b..ab109f7a4 100644 --- a/garden/a-plea-to-organize/index.html +++ b/garden/a-plea-to-organize/index.html @@ -6,14 +6,14 @@ A Plea to Organize | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

A Plea to Organize

1135 words, ~6 minute read. Planted +

Skip to content

A Plea to Organize

1135 words, ~6 minute read. Planted . Last tended to -.


Referenced by:Leftism

If you take one message from this letter, let it be this: Organize! Seek out a local mutual aid group via Mutual Aid Hub or join a progressive political organization like the DSA. Whether you're providing aid, receiving it, or working alongside fellow progressives, solidarity is our strongest tool.

The following is both a call to action and a guide for building a socialist movement that will not only resist but overcome the regressive forces steering our nation.

The Democrat Party has Betrayed You

The US is also a one party state but with typical American extravagance, they have two of them.
-Julius Nyerere

Trump's victory isn't simply a failure of the American electorate—it highlights the absence of a true progressive candidate. The Democrat Party, despite its claims, hasn't delivered on key progressive issues. From the civil rights movement to women's suffrage to gay rights, change has always come from grassroots struggle, not the political elites. The Democrat party's consistent move rightward has betrayed working-class interests, serving capitalist agendas instead.

While the Biden administration touts economic recovery, public sentiment doesn't match. Wage stagnation, unaffordable housing, and unaddressed inflation expose the gap between their rhetoric and the lived experiences of most Americans. Despite popular support and a government trifecta, his administration failed to raise the national minimum wage or fix it to inflation. They've failed to institute or expand price controls on food or rent. They passed the inflation reduction act of 2022, but it was not enough.

Harris' platform was not even socially progressive, as evidenced by their non-action on trans rights. Harris dodging a question a month before the election about protecting trans rights by saying "follow the law", despite the law currently being transphobic and actively getting worse in many states. She then took a transmedicalist stance on trans rights, saying she only supported gender-affirming care when a doctor deemed it "medically necessary".

Harris campaigned on unity, which to her meant courting Republican figures, most notably Dick Cheney and his daughter Liz Cheney. This underscores the Democrats' strategy: appeal to the right, even at the expense of progressive values. This is why "pushing the party left" is a pipe dream - the DNC would rather lose elections than adopt a truly progressive platform. The most clear example of such resistance to progressivism is when they ensured Bernie Sanders could not win the 2016 primaries.

We Need a Progressive Movement

We may have all come on different ships, but we're in the same boat now.
- Dr. Martin Luther King Jr.

America is at a crossroads. The re-election of Trump signals a dangerous shift toward reactionary politics, but we can't rely on the Democratic Party to provide an alternative.

Direct action, especially mutual aid efforts, will be crucial in the coming years. Many marginalized communities will be targeted by the state, and we must be ready to provide support outside of traditional systems that have repeatedly failed them. You can find local mutual aid groups through Mutual Aid Hub, and help your local community.

Trans rights are currently under attack both nationally and in most states. You can use the Trans Legislation Tracker to keep up to date, and from there you can contact your representatives or join local protests.

Joining local progressive organizations, such as the Democratic Socialists of America (DSA) or even fully socialist ones like the Party for Socialism and Liberation (PSL), will help build a strong foundation for a larger political movement. These organizations can serve as vehicles for collective action, allowing us to pool resources, share knowledge, and coordinate efforts on a larger scale.

If you have local unions or cooperatives you can join or support, that will also help your fellow workers and increase the visibility across America of democratic socialist structures working.

Eventually, our goal must be to replace the Democrat party with a legitimately progressive party. Various progressive policies and ideals are gaining popularity across the nation, regardless of political affiliation: impactful policies like protecting abortion rights, raising the minimum wage, universal healthcare, or protecting trans people are supported by most Americans. This election campaign has shown us appealing to the right does not bring in new voters, so we must appeal to the left, addressing the material conditions of the working class and uniting people around a shared vision of a better future.

Don't be Neutral

First they came for the socialists, and I did not speak out—
Because I was not a socialist...
- Martin Niemöller

In times of political upheaval, apathy is a luxury we cannot afford. Choosing "neutrality" is tacitly supporting the status quo, which continues to harm marginalized communities and entrenches inequality. But worse than apathy is insisting on civility - demanding "polite" protests while ignoring the injustice that fuels them. As Dr. MLK Jr. warned, prioritizing order over justice will only perpetuate inequality. Real change requires confronting power structures directly, often outside the confines of "acceptable" political channels.

America's political system, with its electoral college, first-past-the-post voting, and powerful lobbying, is inherently undemocratic. These mechanisms are designed to preserve the status quo, limiting real choice and stifling progressive voices. History shows us that meaningful change has rarely come from the ballot box alone but from grassroots activism and sustained pressure. If we want to transform this system, we must do more than vote—we must mobilize, protest, and demand a better future.

Never be deceived that the rich will allow you to vote away their wealth.
- Lucy Parsons

Read Progressive Media

When I gave food to the poor, they called me a saint. When I asked why the poor have no food, they called me a Communist.
- Dom Helder Camara

Mainstream media, owned by the capitalist class, will frame progressive issues as divisive or fringe. They will cover our failures but not our successes, and certainly not report on when we need your help. To break out from this bias, use news sources like Jacobin, Current Affairs, and The Intercept. Check out FAIR, a progressive news source that tackles corporate bias in media. Educate yourself on progressive causes via accessible resources such as Second Thought and Our Changing Climate. And if you have the time, reading political theory and understanding class struggle empowers us to cut through propaganda and equip ourselves for the fight ahead. In a world of influencers and culture war politics, improving our political literacy and seeing beyond the Republican vs Democrat dichotomy is imperative.

The smart way to keep people passive and obedient is to strictly limit the spectrum of acceptable opinion, but allow very lively debate within that spectrum - even encourage the
more critical and dissident views. That gives people the sense.
that there's free thinking going on, while all the time the
presuppositions of the system are being reinforced by the
limits put on the range of the debate.
- Noam Chomsky

Conclusion

It is our duty to fight for our freedom.
It is our duty to win.
We must love each other and support each other.
We have nothing to lose but our chains.
- Assata Shakur

This is a frightening moment in our nation's history, but we are not powerless. By organizing, educating, and building solidarity, we can lay the foundation for a progressive future. Join an organization, get involved in mutual aid, and prepare to support a new party that prioritizes people over profit.

The path ahead is not easy, but it is necessary. Together, we will challenge the establishment, demand justice, and build a society that works for everyone. The struggle is just beginning—let's make sure it ends in victory.

- +.


Referenced by:Leftism

If you take one message from this letter, let it be this: Organize! Seek out a local mutual aid group via Mutual Aid Hub or join a progressive political organization like the DSA. Whether you're providing aid, receiving it, or working alongside fellow progressives, solidarity is our strongest tool.

The following is both a call to action and a guide for building a socialist movement that will not only resist but overcome the regressive forces steering our nation.

The Democrat Party has Betrayed You

The US is also a one party state but with typical American extravagance, they have two of them.
-Julius Nyerere

Trump's victory isn't simply a failure of the American electorate—it highlights the absence of a true progressive candidate. The Democrat Party, despite its claims, hasn't delivered on key progressive issues. From the civil rights movement to women's suffrage to gay rights, change has always come from grassroots struggle, not the political elites. The Democrat party's consistent move rightward has betrayed working-class interests, serving capitalist agendas instead.

While the Biden administration touts economic recovery, public sentiment doesn't match. Wage stagnation, unaffordable housing, and unaddressed inflation expose the gap between their rhetoric and the lived experiences of most Americans. Despite popular support and a government trifecta, his administration failed to raise the national minimum wage or fix it to inflation. They've failed to institute or expand price controls on food or rent. They passed the inflation reduction act of 2022, but it was not enough.

Harris' platform was not even socially progressive, as evidenced by their non-action on trans rights. Harris dodging a question a month before the election about protecting trans rights by saying "follow the law", despite the law currently being transphobic and actively getting worse in many states. She then took a transmedicalist stance on trans rights, saying she only supported gender-affirming care when a doctor deemed it "medically necessary".

Harris campaigned on unity, which to her meant courting Republican figures, most notably Dick Cheney and his daughter Liz Cheney. This underscores the Democrats' strategy: appeal to the right, even at the expense of progressive values. This is why "pushing the party left" is a pipe dream - the DNC would rather lose elections than adopt a truly progressive platform. The most clear example of such resistance to progressivism is when they ensured Bernie Sanders could not win the 2016 primaries.

We Need a Progressive Movement

We may have all come on different ships, but we're in the same boat now.
- Dr. Martin Luther King Jr.

America is at a crossroads. The re-election of Trump signals a dangerous shift toward reactionary politics, but we can't rely on the Democratic Party to provide an alternative.

Direct action, especially mutual aid efforts, will be crucial in the coming years. Many marginalized communities will be targeted by the state, and we must be ready to provide support outside of traditional systems that have repeatedly failed them. You can find local mutual aid groups through Mutual Aid Hub, and help your local community.

Trans rights are currently under attack both nationally and in most states. You can use the Trans Legislation Tracker to keep up to date, and from there you can contact your representatives or join local protests.

Joining local progressive organizations, such as the Democratic Socialists of America (DSA) or even fully socialist ones like the Party for Socialism and Liberation (PSL), will help build a strong foundation for a larger political movement. These organizations can serve as vehicles for collective action, allowing us to pool resources, share knowledge, and coordinate efforts on a larger scale.

If you have local unions or cooperatives you can join or support, that will also help your fellow workers and increase the visibility across America of democratic socialist structures working.

Eventually, our goal must be to replace the Democrat party with a legitimately progressive party. Various progressive policies and ideals are gaining popularity across the nation, regardless of political affiliation: impactful policies like protecting abortion rights, raising the minimum wage, universal healthcare, or protecting trans people are supported by most Americans. This election campaign has shown us appealing to the right does not bring in new voters, so we must appeal to the left, addressing the material conditions of the working class and uniting people around a shared vision of a better future.

Don't be Neutral

First they came for the socialists, and I did not speak out—
Because I was not a socialist...
- Martin Niemöller

In times of political upheaval, apathy is a luxury we cannot afford. Choosing "neutrality" is tacitly supporting the status quo, which continues to harm marginalized communities and entrenches inequality. But worse than apathy is insisting on civility - demanding "polite" protests while ignoring the injustice that fuels them. As Dr. MLK Jr. warned, prioritizing order over justice will only perpetuate inequality. Real change requires confronting power structures directly, often outside the confines of "acceptable" political channels.

America's political system, with its electoral college, first-past-the-post voting, and powerful lobbying, is inherently undemocratic. These mechanisms are designed to preserve the status quo, limiting real choice and stifling progressive voices. History shows us that meaningful change has rarely come from the ballot box alone but from grassroots activism and sustained pressure. If we want to transform this system, we must do more than vote—we must mobilize, protest, and demand a better future.

Never be deceived that the rich will allow you to vote away their wealth.
- Lucy Parsons

Read Progressive Media

When I gave food to the poor, they called me a saint. When I asked why the poor have no food, they called me a Communist.
- Dom Helder Camara

Mainstream media, owned by the capitalist class, will frame progressive issues as divisive or fringe. They will cover our failures but not our successes, and certainly not report on when we need your help. To break out from this bias, use news sources like Jacobin, Current Affairs, and The Intercept. Check out FAIR, a progressive news source that tackles corporate bias in media. Educate yourself on progressive causes via accessible resources such as Second Thought and Our Changing Climate. And if you have the time, reading political theory and understanding class struggle empowers us to cut through propaganda and equip ourselves for the fight ahead. In a world of influencers and culture war politics, improving our political literacy and seeing beyond the Republican vs Democrat dichotomy is imperative.

The smart way to keep people passive and obedient is to strictly limit the spectrum of acceptable opinion, but allow very lively debate within that spectrum - even encourage the
more critical and dissident views. That gives people the sense.
that there's free thinking going on, while all the time the
presuppositions of the system are being reinforced by the
limits put on the range of the debate.
- Noam Chomsky

Conclusion

It is our duty to fight for our freedom.
It is our duty to win.
We must love each other and support each other.
We have nothing to lose but our chains.
- Assata Shakur

This is a frightening moment in our nation's history, but we are not powerless. By organizing, educating, and building solidarity, we can lay the foundation for a progressive future. Join an organization, get involved in mutual aid, and prepare to support a new party that prioritizes people over profit.

The path ahead is not easy, but it is necessary. Together, we will challenge the establishment, demand justice, and build a society that works for everyone. The struggle is just beginning—let's make sure it ends in victory.

+ \ No newline at end of file diff --git a/garden/advent-incremental/index.html b/garden/advent-incremental/index.html index fb52f6842..1a25cd05e 100644 --- a/garden/advent-incremental/index.html +++ b/garden/advent-incremental/index.html @@ -6,14 +6,14 @@ Advent Incremental | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Advent Incremental

104 words, ~1 minute read. Planted +

Skip to content

Advent Incremental

104 words, ~1 minute read. Planted . Last tended to -.


Tags:My ProjectsProfectus

Play it here!

An Open Source game made in Profectus over the course of 1 month by myself and other devs I know in the Incremental Games community!

I had the idea of an advent-style game that unlocked new pieces of content every real-life day a couple days before December started.

This was one of the most hectic months of my life!

I'm super happy with how it turned out. It ended up being way more ambitious than I anticipated but the end result is super large and awesome!

The TV Tropes page on this game mentions some of the cool things about this game

- +.


Tags:My ProjectsProfectus

Play it here!

An Open Source game made in Profectus over the course of 1 month by myself and other devs I know in the Incremental Games community!

I had the idea of an advent-style game that unlocked new pieces of content every real-life day a couple days before December started.

This was one of the most hectic months of my life!

I'm super happy with how it turned out. It ended up being way more ambitious than I anticipated but the end result is super large and awesome!

The TV Tropes page on this game mentions some of the cool things about this game

+ \ No newline at end of file diff --git a/garden/anarchism/index.html b/garden/anarchism/index.html index e8329b262..0b0df05c5 100644 --- a/garden/anarchism/index.html +++ b/garden/anarchism/index.html @@ -6,14 +6,14 @@ Anarchism | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Anarchism

1821 words, ~10 minute read. Planted +

Skip to content

Anarchism

1821 words, ~10 minute read. Planted . Last tended to -.


Referenced by:Decentralized ModerationDigital LocalityIndividualismLeftismLocal CommunitiesMy Political BeliefsRepresentative Democracy

Anarchism is a political philosophy centered around the idea that authoritative hierarchies are unjust, and aim for a society completely devoid of a state. They see a state as inherently self-preservationist and oppressive, thus that it has no place in society nor the transition to an egalitarian society.

Broadly speaking, flavors of anarchism can fall into 3 categories: collectivist anarchism, which is what this article will focus on; individualist anarchism, which are right-wing versions of anarchism based on Individualism; and modern anarchism, which are adaptations of collectivist communism to include additional hierarchies, such as anarcha-feminism which seeks to abolish the patriarchy in addition to class hierarchy. I'm personally biased against individualist anarchism but align with the values present in many collectivist and modern flavors of anarchism. I believe an ideal society is one with strong Local Communities that operate as a collective; spreading power as thinly as possible to avoid the possibility of any individuals becoming corrupt and abusing their power.

Decision Making in Anarchy

Flavors of anarchy will differ on whether decision making should exist at all. Egoism, an individualist flavor of anarchism, argues against not only any kind of collective decision making, but against society itself. Collectivist flavors of anarchism typically allow for group decision making in some form.

Group decision making under anarchism is typically modeled after a flavor of democracy. Majoritarian democracy, or Direct Democracy , is the idea that everyone gets a single vote and a measure passes if most people are in favor of it. A Consensus Democracy as described in Consensus is the idea that measures should only pass if nobody is opposed to it. This typically means in lieu of voting, individuals can "block" a measure by saying they disagree with it in part of in whole, and the polity must then decide to drop the measure or tweak it until it can pass without any blocks. Some forms of consensus democracy will also allow for measures to pass despite a small number of blocks, for the sake of making it feasible without constant gridlock when scaling up.

There are criticism of group decision making as anti-anarchistic in any form. In both of these versions of democracy, the polity is collectively agreeing to have some form of rule or agreement in place, and once agreed to, an individual typically cannot rescind their consent to that rule or agreement. In majoritarian democracy, up to half the polity may have never even given consent for that rule in the first place. Even in consensus democracy, discussions will often break down into compromise and eventual resignation in order to get measures passed, which is not a "true" version of consent. Typically supporters of these decision making processes will justify them as necessary of a society to function.

I'm personally a fan of consensus democracy. I agree with the justification that a society will naturally and necessarily contain social relationships that lead to things like compromises, and that "persuasiveness" is a permissible hierarchy out of necessity for society to exist.

Democracy in Statist Society

As a quick aside, some anarchists are critical of the term "democracy" here, as it may carry baggage of how democracy is implemented in a statist society, or disingenuously try to copy over the positive associations democracy has within western society. An anarchist would typically flat out reject any form of Representative Democracy due to representatives inherently imperfectly abstracting the will of their constituency. They would argue representative democracy strictly gets better the closer you get to everyone having a representative that perfectly matches their positions on all issues, which is of course then equivalent to a direct democracy.

Assigning Roles in Anarchy

A flavor of anarchism that allows for group decision making typically also allows for roles to be assigned. If the group agreed that a specific person is in charge of making sure livestock don't escape, or another person is in charge of drafting a design for a new building being proposed, then that's completely fine. However, no person fulfilling a role should be considered un-replacable, as that imbues that person with unjust coercive power. That means roles should have redundancies and an answer for "what if this person threatens to stop performing their role unless we capitulate to their demands?"

Motivation Under Anarchy

Anarchism relies on the idea that there are enough individuals motivated to systemically fix problems that they will do so without direct personal gain (beyond the problem being solved), and that others will not block those efforts, even if the policy won't help them in particular. I believe this would and does hold true. I believe our society being filled with greedy individuals is primarily caused by our society rewarding greed (see Social Constructs and Materialism). Anarchy Works starts by addressing this argument. Without the profit motive and returning to a culture of collaboration and mutual aid, greed would for the most part become a non-factor in policy making. Those who are already at the top of the hierarchy don't want to lose their position, and have thus been propagandizing that hierarchies are necessary/inevitable, and even just. This concept gets discussed in The Alt-Right Playbook: Always a Bigger Fish.

Accountability under Anarchy

Anarchy requires Police Abolition, as a carceral state is, obviously, a state. Emma Goldman's essays on anarchism include a chapter on Prisons: A Social Crime and Failure. Suffice to say, there is no state sanctioned violence in a state-less society. With that in mind, if someone breaks a rule or otherwise acts anti-socially, the anarchist society will have to rely on other methods of accountability.

Like prison abolitionists, anarchists would prefer systemic solutions to problems. If someone had to steal food from another at risk of starving, the solution is to ensure food (and other needs like shelter and healthcare) are accessible to all. Technology has made it trivial to provide for everyone; In America, there is more food waste than it would take to feed all the hungry, and enough vacant houses to shelter all the homeless. The scarcity is artificial, created by and maintained by those at the top of the hierarchy.

After meeting everyone's needs, crimes should essentially go away. When accidents happen, there's no need for consequences but the community may make changes to help prevent accidents from re-occurring. If the incident was caused by someone's needs not being met (e.g. food or healthcare), then they should be supported rather than punished. For the remaining edge cases, there is typically reliance on social consequences. People are less likely to associate with someone with anti-social tendencies, and that person may eventually just have to leave the community if no one remains who is willing to associate with them. This should be exceedingly rare, however.

Scaling up Anarchy

A core principle of anarchism is "free association", referring to how individuals should be able to freely enter and leave agreements between anarchist organizations. This is freedom to collaborate with whoever and however you like. These organizations are then typically considered rather ephemeral; temporary arrangements that can dissolve at any time as the needs and desires of those within the arrangement change. Scaling this up, it applies to communities/polities as well. A community can freely enter or leave agreements with other communities, and individuals can freely enter and leave those communities.

One thing to be wary of with free association, is that it can incidentally support segregation. It's therefore important for communities to encourage diversity as much as they can, and refuse to associate with bigoted communities, theoretically discouraging those bigoted views through social and material isolation.

Bookchin, a philosopher who was anarchist but abandoned the term while remaining anti-statist, described a society called Communalism which effectively operated as a confederacy of communes. The communes would operate via consensus, and the confederacy by majoritarian rule, dictating things like allowing communes to join or leave the confederacy. This was an attempt at an alternative to anarchism that would more easily scale up, but is considered fairly controversial amongst anarchists.

There is an organizational concept called sociocracy that has roots in several proto-anarchist thinkers. Sociocracy For All describes it as "one particular way to put anarchist values into practice" in Sociocracy and Anarchism. Their structure closely resembles what I've described and advocated for here, and they've provided guides enabling many organizations to uphold anarchist values.

Anarchy and Capitalism

The definition of individualist anarchism, one of the three categories defined in the introduction, is quite contested amongst anarchists. Some deny that its distinct from collectivist socialism and worth consideration, others claim it includes anarcho-capitalism, and yet others deny that capitalism is even compatible with anarchism at all. As the broad categories are just a Social Construct trying to make it easier to analyze different flavors of anarchism, I think its sufficient to say individualist anarchism is not really a useful term, as it typically needs clarification upon use of what individualist anarchism means to that author specifically.

I will take a strong position in favor of the argument that capitalism is inherently incompatible with anarchism, though. Capitalism inherently forms hierarchies by introducing currency as a coercive force that is then required for continued survival. Anarcho-capitalism, the theoretical blending of capitalism and anarchism, argues for a stateless society with a market economy, effectively instituting laissez-faire economics. Anarcho-capitalism argues this market would regulate itself naturally due to the exchange of goods being purely voluntary, however this ignores capitalist incentives that would trend the economy towards wealth accumulating in the hands of the few. This creates a coercive hierarchy, which is not voluntary due to people's need for food, water, and shelter. The only way to avoid this unjust hierarchy would be with a form of regulatory body that would be nothing short of a state. Therefore, anarcho-capitalism is not compatible with anarchism, because despite their shared antipathy towards states, they do not share the underlying antipathy towards hierarchy.

Anarcho-capitalists argue that their vision of anarchism is the only form that could possibly exist in reality, as any other form necessitates a state in order to handle things like the redistribution of private property. However, this argument itself implies the necessity of private property as a concept. Collectivist forms of anarchy such as anarcho-communism or mutualism demonstrate how economies can work without private property.

Anarchy in the Workplace

Typical American corporations are very hierarchical, with a few hands at the top having ultimate say over the company - what it does, how much it pays its employees, who it fires, etc. Worker's co-operatives are alternatives to corporations that are entirely worker owned and operated, with a flat hierarchy that meaningfully improve worker's rights and help shift society more socialist.

This dynamic means technological progress works in employees' favor, rather than owners' (since the employees are the owners). For example, lets say some technological innovation made employees twice as productive. Under a capitalist structure, the owners would have no reason to increase compensation based on the increased production, and in fact would be discouraged from doing so. They'd likely either use the increased productivity to sell more products, or half the workforce to cut down on significant expenditures. Under a socialist or anarchist structure, the needs and desires of the people are most important, so workers are likely to either see increased compensation due to their increased productivity, or reduced hours without a reduction in compensation. The co-operative could still decide to also just utilize the increased productivity without reducing hours nor increasing compensation, but the decision to do so would have been consensually made by the workers themselves, not their boss.

China enacted a policy in 2024 to make all of its corporations operate democratically, with a "Employee Assembly" made up of up to 100 workers, that can decide on things like firing supervisors or, in big companies, appointing 1/3 of the board of directors. That goes a long way in democratizing the remaining private businesses in China.

- +.


Referenced by:Decentralized ModerationDigital LocalityIndividualismLeftismLocal CommunitiesMy Political BeliefsRepresentative Democracy

Anarchism is a political philosophy centered around the idea that authoritative hierarchies are unjust, and aim for a society completely devoid of a state. They see a state as inherently self-preservationist and oppressive, thus that it has no place in society nor the transition to an egalitarian society.

Broadly speaking, flavors of anarchism can fall into 3 categories: collectivist anarchism, which is what this article will focus on; individualist anarchism, which are right-wing versions of anarchism based on Individualism; and modern anarchism, which are adaptations of collectivist communism to include additional hierarchies, such as anarcha-feminism which seeks to abolish the patriarchy in addition to class hierarchy. I'm personally biased against individualist anarchism but align with the values present in many collectivist and modern flavors of anarchism. I believe an ideal society is one with strong Local Communities that operate as a collective; spreading power as thinly as possible to avoid the possibility of any individuals becoming corrupt and abusing their power.

Decision Making in Anarchy

Flavors of anarchy will differ on whether decision making should exist at all. Egoism, an individualist flavor of anarchism, argues against not only any kind of collective decision making, but against society itself. Collectivist flavors of anarchism typically allow for group decision making in some form.

Group decision making under anarchism is typically modeled after a flavor of democracy. Majoritarian democracy, or Direct Democracy , is the idea that everyone gets a single vote and a measure passes if most people are in favor of it. A Consensus Democracy as described in Consensus is the idea that measures should only pass if nobody is opposed to it. This typically means in lieu of voting, individuals can "block" a measure by saying they disagree with it in part of in whole, and the polity must then decide to drop the measure or tweak it until it can pass without any blocks. Some forms of consensus democracy will also allow for measures to pass despite a small number of blocks, for the sake of making it feasible without constant gridlock when scaling up.

There are criticism of group decision making as anti-anarchistic in any form. In both of these versions of democracy, the polity is collectively agreeing to have some form of rule or agreement in place, and once agreed to, an individual typically cannot rescind their consent to that rule or agreement. In majoritarian democracy, up to half the polity may have never even given consent for that rule in the first place. Even in consensus democracy, discussions will often break down into compromise and eventual resignation in order to get measures passed, which is not a "true" version of consent. Typically supporters of these decision making processes will justify them as necessary of a society to function.

I'm personally a fan of consensus democracy. I agree with the justification that a society will naturally and necessarily contain social relationships that lead to things like compromises, and that "persuasiveness" is a permissible hierarchy out of necessity for society to exist.

Democracy in Statist Society

As a quick aside, some anarchists are critical of the term "democracy" here, as it may carry baggage of how democracy is implemented in a statist society, or disingenuously try to copy over the positive associations democracy has within western society. An anarchist would typically flat out reject any form of Representative Democracy due to representatives inherently imperfectly abstracting the will of their constituency. They would argue representative democracy strictly gets better the closer you get to everyone having a representative that perfectly matches their positions on all issues, which is of course then equivalent to a direct democracy.

Assigning Roles in Anarchy

A flavor of anarchism that allows for group decision making typically also allows for roles to be assigned. If the group agreed that a specific person is in charge of making sure livestock don't escape, or another person is in charge of drafting a design for a new building being proposed, then that's completely fine. However, no person fulfilling a role should be considered un-replacable, as that imbues that person with unjust coercive power. That means roles should have redundancies and an answer for "what if this person threatens to stop performing their role unless we capitulate to their demands?"

Motivation Under Anarchy

Anarchism relies on the idea that there are enough individuals motivated to systemically fix problems that they will do so without direct personal gain (beyond the problem being solved), and that others will not block those efforts, even if the policy won't help them in particular. I believe this would and does hold true. I believe our society being filled with greedy individuals is primarily caused by our society rewarding greed (see Social Constructs and Materialism). Anarchy Works starts by addressing this argument. Without the profit motive and returning to a culture of collaboration and mutual aid, greed would for the most part become a non-factor in policy making. Those who are already at the top of the hierarchy don't want to lose their position, and have thus been propagandizing that hierarchies are necessary/inevitable, and even just. This concept gets discussed in The Alt-Right Playbook: Always a Bigger Fish.

Accountability under Anarchy

Anarchy requires Police Abolition, as a carceral state is, obviously, a state. Emma Goldman's essays on anarchism include a chapter on Prisons: A Social Crime and Failure. Suffice to say, there is no state sanctioned violence in a state-less society. With that in mind, if someone breaks a rule or otherwise acts anti-socially, the anarchist society will have to rely on other methods of accountability.

Like prison abolitionists, anarchists would prefer systemic solutions to problems. If someone had to steal food from another at risk of starving, the solution is to ensure food (and other needs like shelter and healthcare) are accessible to all. Technology has made it trivial to provide for everyone; In America, there is more food waste than it would take to feed all the hungry, and enough vacant houses to shelter all the homeless. The scarcity is artificial, created by and maintained by those at the top of the hierarchy.

After meeting everyone's needs, crimes should essentially go away. When accidents happen, there's no need for consequences but the community may make changes to help prevent accidents from re-occurring. If the incident was caused by someone's needs not being met (e.g. food or healthcare), then they should be supported rather than punished. For the remaining edge cases, there is typically reliance on social consequences. People are less likely to associate with someone with anti-social tendencies, and that person may eventually just have to leave the community if no one remains who is willing to associate with them. This should be exceedingly rare, however.

Scaling up Anarchy

A core principle of anarchism is "free association", referring to how individuals should be able to freely enter and leave agreements between anarchist organizations. This is freedom to collaborate with whoever and however you like. These organizations are then typically considered rather ephemeral; temporary arrangements that can dissolve at any time as the needs and desires of those within the arrangement change. Scaling this up, it applies to communities/polities as well. A community can freely enter or leave agreements with other communities, and individuals can freely enter and leave those communities.

One thing to be wary of with free association, is that it can incidentally support segregation. It's therefore important for communities to encourage diversity as much as they can, and refuse to associate with bigoted communities, theoretically discouraging those bigoted views through social and material isolation.

Bookchin, a philosopher who was anarchist but abandoned the term while remaining anti-statist, described a society called Communalism which effectively operated as a confederacy of communes. The communes would operate via consensus, and the confederacy by majoritarian rule, dictating things like allowing communes to join or leave the confederacy. This was an attempt at an alternative to anarchism that would more easily scale up, but is considered fairly controversial amongst anarchists.

There is an organizational concept called sociocracy that has roots in several proto-anarchist thinkers. Sociocracy For All describes it as "one particular way to put anarchist values into practice" in Sociocracy and Anarchism. Their structure closely resembles what I've described and advocated for here, and they've provided guides enabling many organizations to uphold anarchist values.

Anarchy and Capitalism

The definition of individualist anarchism, one of the three categories defined in the introduction, is quite contested amongst anarchists. Some deny that its distinct from collectivist socialism and worth consideration, others claim it includes anarcho-capitalism, and yet others deny that capitalism is even compatible with anarchism at all. As the broad categories are just a Social Construct trying to make it easier to analyze different flavors of anarchism, I think its sufficient to say individualist anarchism is not really a useful term, as it typically needs clarification upon use of what individualist anarchism means to that author specifically.

I will take a strong position in favor of the argument that capitalism is inherently incompatible with anarchism, though. Capitalism inherently forms hierarchies by introducing currency as a coercive force that is then required for continued survival. Anarcho-capitalism, the theoretical blending of capitalism and anarchism, argues for a stateless society with a market economy, effectively instituting laissez-faire economics. Anarcho-capitalism argues this market would regulate itself naturally due to the exchange of goods being purely voluntary, however this ignores capitalist incentives that would trend the economy towards wealth accumulating in the hands of the few. This creates a coercive hierarchy, which is not voluntary due to people's need for food, water, and shelter. The only way to avoid this unjust hierarchy would be with a form of regulatory body that would be nothing short of a state. Therefore, anarcho-capitalism is not compatible with anarchism, because despite their shared antipathy towards states, they do not share the underlying antipathy towards hierarchy.

Anarcho-capitalists argue that their vision of anarchism is the only form that could possibly exist in reality, as any other form necessitates a state in order to handle things like the redistribution of private property. However, this argument itself implies the necessity of private property as a concept. Collectivist forms of anarchy such as anarcho-communism or mutualism demonstrate how economies can work without private property.

Anarchy in the Workplace

Typical American corporations are very hierarchical, with a few hands at the top having ultimate say over the company - what it does, how much it pays its employees, who it fires, etc. Worker's co-operatives are alternatives to corporations that are entirely worker owned and operated, with a flat hierarchy that meaningfully improve worker's rights and help shift society more socialist.

This dynamic means technological progress works in employees' favor, rather than owners' (since the employees are the owners). For example, lets say some technological innovation made employees twice as productive. Under a capitalist structure, the owners would have no reason to increase compensation based on the increased production, and in fact would be discouraged from doing so. They'd likely either use the increased productivity to sell more products, or half the workforce to cut down on significant expenditures. Under a socialist or anarchist structure, the needs and desires of the people are most important, so workers are likely to either see increased compensation due to their increased productivity, or reduced hours without a reduction in compensation. The co-operative could still decide to also just utilize the increased productivity without reducing hours nor increasing compensation, but the decision to do so would have been consensually made by the workers themselves, not their boss.

China enacted a policy in 2024 to make all of its corporations operate democratically, with a "Employee Assembly" made up of up to 100 workers, that can decide on things like firing supervisors or, in big companies, appointing 1/3 of the board of directors. That goes a long way in democratizing the remaining private businesses in China.

+ \ No newline at end of file diff --git a/garden/art-is-never-complete/index.html b/garden/art-is-never-complete/index.html index bb514bb8b..072549419 100644 --- a/garden/art-is-never-complete/index.html +++ b/garden/art-is-never-complete/index.html @@ -6,14 +6,14 @@ Art is Never Complete | The Paper Pilot - + - + - - - + + + @@ -53,9 +53,9 @@ -
Skip to content

Art is Never Complete

92 words, ~1 minute read. Planted -.


Referenced by:Guide to Incrementals/What is Content?

Art is never finished, only abandoned. - Leonardo Da Vinci

This quote intrigues me and feels quite relatable. I've struggled with perfectionism (and in fact it's a large theme in Kronos), something Leonardo famously did as well. This quote feels like an exit ticket to getting out of perfectionist thinking - if art is never finished, then when its "done" (abandoned) is arbitrary. Perhaps that's why Leonardo left so many WIPs behind in his journal - if the point at which you abandon them is arbitrary, then why not abandon projects early?

- +
Skip to content

Art is Never Complete

92 words, ~1 minute read. Planted +.


Referenced by:Guide to Incrementals/What is Content?

Art is never finished, only abandoned. - Leonardo Da Vinci

This quote intrigues me and feels quite relatable. I've struggled with perfectionism (and in fact it's a large theme in Kronos), something Leonardo famously did as well. This quote feels like an exit ticket to getting out of perfectionist thinking - if art is never finished, then when its "done" (abandoned) is arbitrary. Perhaps that's why Leonardo left so many WIPs behind in his journal - if the point at which you abandon them is arbitrary, then why not abandon projects early?

+ \ No newline at end of file diff --git a/garden/artificial-intelligence/index.html b/garden/artificial-intelligence/index.html index c164a3913..f9a39bf77 100644 --- a/garden/artificial-intelligence/index.html +++ b/garden/artificial-intelligence/index.html @@ -6,14 +6,14 @@ Artificial Intelligence | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Artificial Intelligence

101 words, ~1 minute read. Planted +

Skip to content

Artificial Intelligence

101 words, ~1 minute read. Planted . Last tended to -.


Referenced by:Command Palettes

Catch all term that refers to many different things

Generative AI

  • Models trained on large amounts of existing human made content in order to produce more of that content
  • Copyright concerns over how training data is obtained
  • Common Examples

Human + AI cooperation

- +.


Referenced by:Command Palettes

Catch all term that refers to many different things

Generative AI

  • Models trained on large amounts of existing human made content in order to produce more of that content
  • Copyright concerns over how training data is obtained
  • Common Examples

Human + AI cooperation

+ \ No newline at end of file diff --git a/garden/atproto/index.html b/garden/atproto/index.html index 0eabc38c3..5ed3ddcec 100644 --- a/garden/atproto/index.html +++ b/garden/atproto/index.html @@ -6,14 +6,14 @@ ATProto | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

ATProto

14 words, ~0 minute read. Planted +

Skip to content

ATProto

14 words, ~0 minute read. Planted . Last tended to -.


Referenced by:Decentralized ModerationFediverse

The AT Protocol is a protocol for Federated Social Media created by Bluesky. In comparison to other Fediverse protocols, ATProto is designed for a small number of large instances.

- +.


Referenced by:Decentralized ModerationFediverse

The AT Protocol is a protocol for Federated Social Media created by Bluesky. In comparison to other Fediverse protocols, ATProto is designed for a small number of large instances.

+ \ No newline at end of file diff --git a/garden/babble-buds/index.html b/garden/babble-buds/index.html index e1e8b817d..902232c79 100644 --- a/garden/babble-buds/index.html +++ b/garden/babble-buds/index.html @@ -6,14 +6,14 @@ Babble Buds | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Babble Buds

113 words, ~1 minute read. Planted +

Skip to content

Babble Buds

113 words, ~1 minute read. Planted . Last tended to -.


Tags:My Projects

Babble Buds is a tool for creating puppets and interacting with puppets controlled by others on a shared stage

Note: I need to move the website off replit because of their monetization strategy changing. In the meantime, you can check it out from its github repository

Inspired by Puppet Pals by Robert Moran

Intended for use in RPG Campaigns

The renderer was separated into its own project, babble.js, so it could be used for stuff like cutscenes

I ported the engine to C# and used it for the cutscenes in Dice Armor

  • I don't believe I ever separated it out into its own project, but you can find the code here
- +.


Tags:My Projects

Babble Buds is a tool for creating puppets and interacting with puppets controlled by others on a shared stage

Note: I need to move the website off replit because of their monetization strategy changing. In the meantime, you can check it out from its github repository

Inspired by Puppet Pals by Robert Moran

Intended for use in RPG Campaigns

The renderer was separated into its own project, babble.js, so it could be used for stuff like cutscenes

I ported the engine to C# and used it for the cutscenes in Dice Armor

  • I don't believe I ever separated it out into its own project, but you can find the code here
+ \ No newline at end of file diff --git a/garden/capture-the-citadel/index.html b/garden/capture-the-citadel/index.html index 6a33cd07a..3e2f1433b 100644 --- a/garden/capture-the-citadel/index.html +++ b/garden/capture-the-citadel/index.html @@ -6,14 +6,14 @@ Capture the Citadel | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Capture the Citadel

39 words, ~0 minute read. Planted +

Skip to content

Capture the Citadel

39 words, ~0 minute read. Planted . Last tended to -.


Tags:My Projects

A 3D VR re-envisioning of a Slay the Spire-style game by Anthony Lawn and Grant Barbee for their VR class in college's final project.

For more details, visit Grant's page on the game.

- +.


Tags:My Projects

A 3D VR re-envisioning of a Slay the Spire-style game by Anthony Lawn and Grant Barbee for their VR class in college's final project.

For more details, visit Grant's page on the game.

+ \ No newline at end of file diff --git a/garden/chat-glue/index.html b/garden/chat-glue/index.html index f2da12f70..306b86413 100644 --- a/garden/chat-glue/index.html +++ b/garden/chat-glue/index.html @@ -6,14 +6,14 @@ Chat Glue | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Chat Glue

23 words, ~0 minute read. Planted +

Skip to content

Chat Glue

23 words, ~0 minute read. Planted . Last tended to -.


Referenced by:CommuneThe Small Web

A theoretical chat system designed to solve the problems of transcribing branching conversations into linear timelines.

Defined by the Chatting with Glue comic.

- +.


Referenced by:CommuneThe Small Web

A theoretical chat system designed to solve the problems of transcribing branching conversations into linear timelines.

Defined by the Chatting with Glue comic.

+ \ No newline at end of file diff --git a/garden/chromatic-lattice/index.html b/garden/chromatic-lattice/index.html index 1753f3901..a442c76e3 100644 --- a/garden/chromatic-lattice/index.html +++ b/garden/chromatic-lattice/index.html @@ -6,14 +6,14 @@ Chromatic Lattice | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Chromatic Lattice

189 words, ~1 minute read. Planted +

Skip to content

Chromatic Lattice

189 words, ~1 minute read. Planted . Last tended to -.


Referenced by:Digital LocalityFedi v2Incremental Social/now

A multiplayer game I have in development. It'll be about optimizing a board of tiles to create certain patterns to improve resource gains. Players will work collaboratively to construct monuments. It will be built on the Agentic Fediverse and experiment with Digital Locality.

A person's board will act as their profile page, and will include a local chat room (in addition to the global one), a description, a list of people currently on the page, and a friends list that can be broken down into categories. Your cursor also appears on the board for all other users, although those can be toggled off in settings.

The friend lists effectively work as the links between nodes, creating locality. Everyone has a link to their own board accessible at all times, and from there to their friends. All links would also show a count of how many people are on that board.

In addition to friends, you can jump to a players board or to wherever the player is by right clicking their name in global chat. You can also share links to your board off platform as well.

- +.


Referenced by:Digital LocalityFedi v2Incremental Social/now

A multiplayer game I have in development. It'll be about optimizing a board of tiles to create certain patterns to improve resource gains. Players will work collaboratively to construct monuments. It will be built on the Agentic Fediverse and experiment with Digital Locality.

A person's board will act as their profile page, and will include a local chat room (in addition to the global one), a description, a list of people currently on the page, and a friends list that can be broken down into categories. Your cursor also appears on the board for all other users, although those can be toggled off in settings.

The friend lists effectively work as the links between nodes, creating locality. Everyone has a link to their own board accessible at all times, and from there to their friends. All links would also show a count of how many people are on that board.

In addition to friends, you can jump to a players board or to wherever the player is by right clicking their name in global chat. You can also share links to your board off platform as well.

+ \ No newline at end of file diff --git a/garden/chronological/index.html b/garden/chronological/index.html index d08471471..8d50684e4 100644 --- a/garden/chronological/index.html +++ b/garden/chronological/index.html @@ -6,14 +6,14 @@ Chronological | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Chronological

73 words, ~0 minute read. Planted +

Skip to content

Chronological

73 words, ~0 minute read. Planted . Last tended to -.


Referenced by:Digital GardensFreeform vs Chronological Dichotomy

A collection of information that is tied to its creation or edit date

Part of the Freeform vs Chronological Dichotomy

Anything with a "timeline" or "feed" is considered chronological

  • Even if there's algorithmic sortings that take things other than creation or edit date into account!

Chronological displays are less suitable as stores of knowledge (Digital Gardens)

Social media overuses timelines and feeds

RSS feeds work really well with this form of content

- +.


Referenced by:Digital GardensFreeform vs Chronological Dichotomy

A collection of information that is tied to its creation or edit date

Part of the Freeform vs Chronological Dichotomy

Anything with a "timeline" or "feed" is considered chronological

  • Even if there's algorithmic sortings that take things other than creation or edit date into account!

Chronological displays are less suitable as stores of knowledge (Digital Gardens)

Social media overuses timelines and feeds

RSS feeds work really well with this form of content

+ \ No newline at end of file diff --git a/garden/cinny/index.html b/garden/cinny/index.html index e4f2b359b..be60a819a 100644 --- a/garden/cinny/index.html +++ b/garden/cinny/index.html @@ -6,14 +6,14 @@ Cinny | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Cinny

3 words, ~0 minute read. Planted +

Skip to content

Cinny

3 words, ~0 minute read. Planted . Last tended to -.


Referenced by:Incremental Social

Cinny is an Open Source web client for the Matrix messaging protocol

- +.


Referenced by:Incremental Social

Cinny is an Open Source web client for the Matrix messaging protocol

+ \ No newline at end of file diff --git a/garden/command-palettes/index.html b/garden/command-palettes/index.html index ed71c0746..ea78f251f 100644 --- a/garden/command-palettes/index.html +++ b/garden/command-palettes/index.html @@ -6,14 +6,14 @@ Command Palettes | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Command Palettes

117 words, ~1 minute read. Planted +

Skip to content

Command Palettes

117 words, ~1 minute read. Planted . Last tended to -.


Command palettes are a design pattern where apps expose functionality through a search bar

Typing what you want is almost certainly easier and faster than finding the action in some submenu or remembering an arcane hotkey

  • Especially with fuzzy search that also looks through descriptions of actions
  • Command palettes scale very well with large amounts of actions

Artificial Intelligence will make command palettes increasingly powerful

  • Eventually these may become conversational interfaces

Maggie Appleton discusses this pattern in her article on Command K Bars

  • The name comes from the fact many apps use the ctrl/cmd k shortcut to open the command palette

Many softwares I use have some form of command palette

  • Linear
  • Logseq
  • Visual Studio Code
- +.


Command palettes are a design pattern where apps expose functionality through a search bar

Typing what you want is almost certainly easier and faster than finding the action in some submenu or remembering an arcane hotkey

  • Especially with fuzzy search that also looks through descriptions of actions
  • Command palettes scale very well with large amounts of actions

Artificial Intelligence will make command palettes increasingly powerful

  • Eventually these may become conversational interfaces

Maggie Appleton discusses this pattern in her article on Command K Bars

  • The name comes from the fact many apps use the ctrl/cmd k shortcut to open the command palette

Many softwares I use have some form of command palette

  • Linear
  • Logseq
  • Visual Studio Code
+ \ No newline at end of file diff --git a/garden/commune/index.html b/garden/commune/index.html index 358d2f80c..297e55d8d 100644 --- a/garden/commune/index.html +++ b/garden/commune/index.html @@ -6,14 +6,14 @@ Commune | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Commune

144 words, ~1 minute read. Planted +

Skip to content

Commune

144 words, ~1 minute read. Planted . Last tended to -.


Referenced by:Digital LocalityFilter BubblesOrchardWebringsWeird

An Open Source Matrix web client built to be better for communities than anything else out there

  • Currently in development
  • Exposes certain channels such that they are web indexable
  • Will include features like Chat Glue and communal Digital Gardens

Created by Erlend Sogge Heggen, a ex-employee from Discourse

  • Maintains the Commune Blog with great write ups on the issues of the modern web, social media, etc. and how they can be improved (by Commune or related projects)
  • Also maintains a Personal Blog about similar topics

The Commune community is very interested in various topics and how they can relate together:

Related projects:

  • @laxla@tech.lgbt is creating Gimli, a federated discord alternative
    • Built on ActivityPub
    • "Guild-based" in ways matrix is not?
    • Will integrate with F3 as well
    • Wants to handle blogging as well
    • Certainly seems similar to Commune's message gardening concept
- +.


Referenced by:Digital LocalityFilter BubblesOrchardWebringsWeird

An Open Source Matrix web client built to be better for communities than anything else out there

  • Currently in development
  • Exposes certain channels such that they are web indexable
  • Will include features like Chat Glue and communal Digital Gardens

Created by Erlend Sogge Heggen, a ex-employee from Discourse

  • Maintains the Commune Blog with great write ups on the issues of the modern web, social media, etc. and how they can be improved (by Commune or related projects)
  • Also maintains a Personal Blog about similar topics

The Commune community is very interested in various topics and how they can relate together:

Related projects:

  • @laxla@tech.lgbt is creating Gimli, a federated discord alternative
    • Built on ActivityPub
    • "Guild-based" in ways matrix is not?
    • Will integrate with F3 as well
    • Wants to handle blogging as well
    • Certainly seems similar to Commune's message gardening concept
+ \ No newline at end of file diff --git a/garden/consensus-democracy/index.html b/garden/consensus-democracy/index.html index a852ef516..fdf650d21 100644 --- a/garden/consensus-democracy/index.html +++ b/garden/consensus-democracy/index.html @@ -6,14 +6,14 @@ Consensus Democracy | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Consensus Democracy

213 words, ~1 minute read. Planted +

Skip to content

Consensus Democracy

213 words, ~1 minute read. Planted . Last tended to -.


Referenced by:AnarchismGerrymanderingMy Political Beliefs

A form of democracy similar to Direct Democracy but with higher requirements for passing policies, typically requiring unanimity or near-unanimity. This helps reduce (although doesn't eliminate) the possibility of a majority group oppressing a minority group.

Consensus democracy encourages and requires innovative solutions to problems (similar to Police Abolition) and pragmatic compromises. However, this can make them susceptible to "design by committee" and can make policies impossibly difficult to pass for large groups of people.

Since consensus democracy doesn't scale well, larger governments could be structured as a federation of smaller governments. The smaller governments still use consensus democracy, but the federation only adopts policies that a super-majority of the smaller governments have agreed upon. Alternatively, the federation could specifically ask the local governments for policy proposals, then use Direct Democracy to decide whether to approve it or not, still requiring a super-majority.

For policies that still are unable to pass federally, local governments could form coalitions that organize larger-scale initiatives between several districts where there is consensus support. For example, this could empower efforts like transit systems between districts. These coalitions could possibly end up making the federal level obsolete, and ensure people are still only subject to laws and policies that made it through consensus.

Transitioning to a direct democracy will face difficulties in finding an initial set of rules that people can agree with.

- +.


Referenced by:AnarchismGerrymanderingMy Political Beliefs

A form of democracy similar to Direct Democracy but with higher requirements for passing policies, typically requiring unanimity or near-unanimity. This helps reduce (although doesn't eliminate) the possibility of a majority group oppressing a minority group.

Consensus democracy encourages and requires innovative solutions to problems (similar to Police Abolition) and pragmatic compromises. However, this can make them susceptible to "design by committee" and can make policies impossibly difficult to pass for large groups of people.

Since consensus democracy doesn't scale well, larger governments could be structured as a federation of smaller governments. The smaller governments still use consensus democracy, but the federation only adopts policies that a super-majority of the smaller governments have agreed upon. Alternatively, the federation could specifically ask the local governments for policy proposals, then use Direct Democracy to decide whether to approve it or not, still requiring a super-majority.

For policies that still are unable to pass federally, local governments could form coalitions that organize larger-scale initiatives between several districts where there is consensus support. For example, this could empower efforts like transit systems between districts. These coalitions could possibly end up making the federal level obsolete, and ensure people are still only subject to laws and policies that made it through consensus.

Transitioning to a direct democracy will face difficulties in finding an initial set of rules that people can agree with.

+ \ No newline at end of file diff --git a/garden/davey-wreden/index.html b/garden/davey-wreden/index.html index 7c7b3abc9..7f52b1152 100644 --- a/garden/davey-wreden/index.html +++ b/garden/davey-wreden/index.html @@ -6,14 +6,14 @@ Davey Wreden | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Davey Wreden

37 words, ~0 minute read. Planted +

Skip to content
- +.


Referenced by:Ivy RoadThe Beginner's Guide
Tagged by:Ivy RoadThe Beginner's GuideWanderstop

Projects:

Talks and Interviews:

+ \ No newline at end of file diff --git a/garden/debate/index.html b/garden/debate/index.html index 5e486663a..0cfe87657 100644 --- a/garden/debate/index.html +++ b/garden/debate/index.html @@ -6,14 +6,14 @@ Debate | The Paper Pilot - + - + - - - + + + @@ -53,9 +53,9 @@ -
Skip to content

Debate

986 words, ~5 minute read. Planted -.


Referenced by:"No Politics" Rules

Debate takes many forms, but for this article we're going to group them into three categories, and argue why none of them work towards actually finding the best solution to a problem. These categories are going to be structured debates, public debates, and conversational debates.

Structured debates

These are the formal debates held in academic contexts and tournaments. These have predefined formats like Lincoln-Douglas or Oxford style, and have the explicit goal of one of the individuals being judged as the winner not based on having the correct stance or even making good arguments, but for their performance in the debate, dictated by their charisma and rhetoric and ability to respond quickly.

While specific formats vary, many of these debates are filled with gish galloping and other rhetorical flourishes. Gish galloping is when a debater speeds through many arguments with the goal of overwhelming the adversary, as its easier and faster to make unsubstantiated claims than it is to contest them. This is a common technique not just in structured debates but all debates. If you're ever watched Ben Shapiro debate (and you have my sympathies), you've seen the gish gallop technique in action.

These debates are adversarial by design, and there is no opportunity for constructive discussion aimed at arriving at the correct conclusion. The people participating in these debates certainly prepare greatly for arguing their positions, but additionally learn a great many skills and techniques unique to the formal debate format.

It should likely go without saying, but this is clearly not meant to be how new ideas are formed or how solutions get created. This is an academic exercise completely divorced from actually solving the problems in our society. The debates are not intended to influence people or impact policy. The skills developed here do not translate to collaborative problem-solving environments.

Public debates

Public debates are debates held by public figures, such as the presidential debates or debates involving political pundits like Ben Shapiro or Cenk Uyghur. They don't have judges or formal winners and losers. Similar to structured debates, these are adversarial debates that don't aim to form a consensus by the end of the debate. Instead, the goal here is for each debater to improve public sentiment towards themselves.

Gish galloping and its companion reverse gish galloping, whereby a flaw in one specific point is used to dismiss the entire argument, are commonly used here, alongside ad hominem attacks and other fallacies. Since the goal is to change public perception, appeals to emotion work greatly here.

As before, these are not intended to change the minds of either participant. They may influence the audience to view a participant or their position more favorably, but this isn't some victory for the "free market of ideas" - the influence is still tied more to the participants' charisma and rhetorical skill rather than the correctness of their position. Several on the left have argued against the utility of these debates, debate culture, and "debate bro" influencers, such as Wisecrack and Noah Samsen.

Conversational debates

This refers to impromptu political discourse, and typically happens between non-influencers on social media. Its debate for the rest of us! Since this is inherently informal there's no enforced structure, but typically they're adversarial since the conversation starts by someone taking issue with something someone else said.

As with the other types, being adversarial means closing one's mind and framing the debate as a competition with a winner and a loser rather than a constructive conversation building towards consensus. One's ego gets intertwined with being correct, and conceding points becomes akin to admitting personal failures.

Being conversational, participants can come and go and anyone can try initiating arguments. This gives rise to sealioning, a form of bad faith debater that exhausts others with their continuous requests for citations or other responses under the pretense of civility. While they can be grating on anyone, their especially a problem for influencers or those who "go viral". The issue is the sheer amount of criticism, the mental and emotional drain filtering through it can be, and the nebulousness of what even is "valid criticism". Innuendo Studios discussed this concept in Why Don't You Respond to Criticism?.

Alternatives to debate

Improving your understanding

If you want to better understand these issues and have an open mind, then read a book. Those who you would be arguing against will not have as good an understanding of political theory as books written by the experts. It won't give you the pleasure of having "beaten someone in the free market of ideas", but it's the best way for you to actually understand the underlying philosophies that compose different political ideologies. Ask me if you'd like any recommendations for getting into Leftist thought 🙂.

In general, become skeptical of political discourse you see in the media, mainstream or social or otherwise. Keep in mind these are people trying to "win" and change minds, and are likely not delving into underlying theory. Clips of gotcha moments or isolated "good points" may feel good to share, but they are unlikely to change minds.

Improving others' understanding

If you want to convince others to shift their political stance, then recommending books for them to read is also probably your best bet. You can assist someone on their political journey, but you can't force them onto it. If you fancy yourself skilled at distilling information and already have a very good understanding of not just the position you're arguing but the underlying theory, then by all means you can write your own "explainers" on the topic and distribute those as well. May I propose a Digital Garden?

Being productive

Rather than having political discourse for its own sake, apply the topic to something that can be acted upon, such as changing a rule within the community (might I suggest discussing a replacement or set of replacement rules to get rid of an existing "No Politics" Rule 😉). These are much more likely to work constructively towards finding consensus, and can actually lead to productive changes that affect the participants. You'll see issues raised and be able to find ways to solve them amicably rather than trying to dismiss them. Naturally this only applies in certain contexts and discussing current events won't often be translatable to the community directly.

Also, don't neglect your physical community. All of this article has been centering on online conversations, but if your goal is to be productive and make meaningful change, then go out and do something! Join a local org - I recommend checking out Mutual Aid Hub, but a local political org can also help with mobilizing for protests and other events, which supports the cause far more than arguing with strangers on the internet. The specific org doesn't matter too much - one's political journey will likely involve multiple orgs - but meeting up with comrades offline at all will provide useful and fulfilling experiences. There's a list of leftist organizations here to help you in your search; it has a lot of other useful resources as well.

- +
Skip to content

Debate

986 words, ~5 minute read. Planted +.


Referenced by:"No Politics" Rules

Debate takes many forms, but for this article we're going to group them into three categories, and argue why none of them work towards actually finding the best solution to a problem. These categories are going to be structured debates, public debates, and conversational debates.

Structured debates

These are the formal debates held in academic contexts and tournaments. These have predefined formats like Lincoln-Douglas or Oxford style, and have the explicit goal of one of the individuals being judged as the winner not based on having the correct stance or even making good arguments, but for their performance in the debate, dictated by their charisma and rhetoric and ability to respond quickly.

While specific formats vary, many of these debates are filled with gish galloping and other rhetorical flourishes. Gish galloping is when a debater speeds through many arguments with the goal of overwhelming the adversary, as its easier and faster to make unsubstantiated claims than it is to contest them. This is a common technique not just in structured debates but all debates. If you're ever watched Ben Shapiro debate (and you have my sympathies), you've seen the gish gallop technique in action.

These debates are adversarial by design, and there is no opportunity for constructive discussion aimed at arriving at the correct conclusion. The people participating in these debates certainly prepare greatly for arguing their positions, but additionally learn a great many skills and techniques unique to the formal debate format.

It should likely go without saying, but this is clearly not meant to be how new ideas are formed or how solutions get created. This is an academic exercise completely divorced from actually solving the problems in our society. The debates are not intended to influence people or impact policy. The skills developed here do not translate to collaborative problem-solving environments.

Public debates

Public debates are debates held by public figures, such as the presidential debates or debates involving political pundits like Ben Shapiro or Cenk Uyghur. They don't have judges or formal winners and losers. Similar to structured debates, these are adversarial debates that don't aim to form a consensus by the end of the debate. Instead, the goal here is for each debater to improve public sentiment towards themselves.

Gish galloping and its companion reverse gish galloping, whereby a flaw in one specific point is used to dismiss the entire argument, are commonly used here, alongside ad hominem attacks and other fallacies. Since the goal is to change public perception, appeals to emotion work greatly here.

As before, these are not intended to change the minds of either participant. They may influence the audience to view a participant or their position more favorably, but this isn't some victory for the "free market of ideas" - the influence is still tied more to the participants' charisma and rhetorical skill rather than the correctness of their position. Several on the left have argued against the utility of these debates, debate culture, and "debate bro" influencers, such as Wisecrack and Noah Samsen.

Conversational debates

This refers to impromptu political discourse, and typically happens between non-influencers on social media. Its debate for the rest of us! Since this is inherently informal there's no enforced structure, but typically they're adversarial since the conversation starts by someone taking issue with something someone else said.

As with the other types, being adversarial means closing one's mind and framing the debate as a competition with a winner and a loser rather than a constructive conversation building towards consensus. One's ego gets intertwined with being correct, and conceding points becomes akin to admitting personal failures.

Being conversational, participants can come and go and anyone can try initiating arguments. This gives rise to sealioning, a form of bad faith debater that exhausts others with their continuous requests for citations or other responses under the pretense of civility. While they can be grating on anyone, their especially a problem for influencers or those who "go viral". The issue is the sheer amount of criticism, the mental and emotional drain filtering through it can be, and the nebulousness of what even is "valid criticism". Innuendo Studios discussed this concept in Why Don't You Respond to Criticism?.

Alternatives to debate

Improving your understanding

If you want to better understand these issues and have an open mind, then read a book. Those who you would be arguing against will not have as good an understanding of political theory as books written by the experts. It won't give you the pleasure of having "beaten someone in the free market of ideas", but it's the best way for you to actually understand the underlying philosophies that compose different political ideologies. Ask me if you'd like any recommendations for getting into Leftist thought 🙂.

In general, become skeptical of political discourse you see in the media, mainstream or social or otherwise. Keep in mind these are people trying to "win" and change minds, and are likely not delving into underlying theory. Clips of gotcha moments or isolated "good points" may feel good to share, but they are unlikely to change minds.

Improving others' understanding

If you want to convince others to shift their political stance, then recommending books for them to read is also probably your best bet. You can assist someone on their political journey, but you can't force them onto it. If you fancy yourself skilled at distilling information and already have a very good understanding of not just the position you're arguing but the underlying theory, then by all means you can write your own "explainers" on the topic and distribute those as well. May I propose a Digital Garden?

Being productive

Rather than having political discourse for its own sake, apply the topic to something that can be acted upon, such as changing a rule within the community (might I suggest discussing a replacement or set of replacement rules to get rid of an existing "No Politics" Rule 😉). These are much more likely to work constructively towards finding consensus, and can actually lead to productive changes that affect the participants. You'll see issues raised and be able to find ways to solve them amicably rather than trying to dismiss them. Naturally this only applies in certain contexts and discussing current events won't often be translatable to the community directly.

Also, don't neglect your physical community. All of this article has been centering on online conversations, but if your goal is to be productive and make meaningful change, then go out and do something! Join a local org - I recommend checking out Mutual Aid Hub, but a local political org can also help with mobilizing for protests and other events, which supports the cause far more than arguing with strangers on the internet. The specific org doesn't matter too much - one's political journey will likely involve multiple orgs - but meeting up with comrades offline at all will provide useful and fulfilling experiences. There's a list of leftist organizations here to help you in your search; it has a lot of other useful resources as well.

+ \ No newline at end of file diff --git a/garden/decentralized-identity/index.html b/garden/decentralized-identity/index.html index c287123e1..3abc8209e 100644 --- a/garden/decentralized-identity/index.html +++ b/garden/decentralized-identity/index.html @@ -6,14 +6,14 @@ Decentralized Identity | The Paper Pilot - + - + - - - + + + @@ -53,9 +53,9 @@ -
Skip to content

Decentralized Identity

532 words, ~3 minute read. Planted -.


Referenced by:CommuneDecentralized Social MediaFedi v2Incremental SocialNostrWeird
Tags:Decentralized

Decentralized identity is when someone's identity can be authenticated without the reliance of a central authoritative source. Keypairs are the most common form of this, where someone generates a pair of keys - one private and one public, with which they can sign a message in a way that allows others to verify it came from someone with access to the private key and was not tampered with. IndieAuth is another version of decentralized identity, used by parts of The IndieWeb.

User Experience

Clients can silently generate key pairs, and allow methods for migration or "linking" identities. The client could also include backup methods like saving the private key to Google drive or similar services. The point here would to have convenient default choices that are reasonably secure, while allowing people to have full agency to choose their own storage and backup solutions.

Sharing your profile with others may be tricky. If you're registered on a nameserver then you can just share your handle there, similar to fediverse profile handles. Otherwise, I think QR codes are the most user friendly solution. A client could register a URI handler that takes a public key and optionally a relay server that has the information about that identity. Adding the identity to your friends list could happen fully offline, although pulling the profile information would require a connection. Perhaps that, too, could be encoded in a (likely separate) QR code.

Profile Information

For casual conversation, a nickname in the profile data should be sufficient. Once a client interacts with someone, they can be added as a contact as a way of verifying the next conversation with someone with that username is actually the same person as before.

For situations where you want to verify an identity actually has a credentials they claim, you can query a nameserver that vouches for them. For example, whitehouse.gov would have a nameserver that specifies which identity is the actual president of the United States (and other government officials).

There could be nameservers that allow you to openly "register" your identity with them to get a unique human readable username you can include on billboards or other visual media where you want someone to be able to memorize the identifier, rather than scan a QR code or something.

For more details on how these decentralized usernames would work, check out Petnames.

Identity Recovery

If you lose access to your account, it's gone forever. That is why I think there should be defaults to backup your private key to existing reliable servers, even if they're owned by large corporations. Otherwise I would see someone have their phone stolen, lost, or upgraded and be surprised when their account is now inaccessible.

If you do lose your account and create a new identity, you could have others "vouch" for the new identity being an alias for the previous identity. You could verify your new identity with people IRL, and then other clients can see those vouches publicly and, after sufficient quantity, just implicitly assume they're the same (although with some sort of indicator, so if this gets abused, users are at least aware of the possibility of impersonation.

- +
Skip to content

Decentralized Identity

532 words, ~3 minute read. Planted +.


Referenced by:CommuneDecentralized Social MediaFedi v2Incremental SocialNostrWeird
Tags:Decentralized

Decentralized identity is when someone's identity can be authenticated without the reliance of a central authoritative source. Keypairs are the most common form of this, where someone generates a pair of keys - one private and one public, with which they can sign a message in a way that allows others to verify it came from someone with access to the private key and was not tampered with. IndieAuth is another version of decentralized identity, used by parts of The IndieWeb.

User Experience

Clients can silently generate key pairs, and allow methods for migration or "linking" identities. The client could also include backup methods like saving the private key to Google drive or similar services. The point here would to have convenient default choices that are reasonably secure, while allowing people to have full agency to choose their own storage and backup solutions.

Sharing your profile with others may be tricky. If you're registered on a nameserver then you can just share your handle there, similar to fediverse profile handles. Otherwise, I think QR codes are the most user friendly solution. A client could register a URI handler that takes a public key and optionally a relay server that has the information about that identity. Adding the identity to your friends list could happen fully offline, although pulling the profile information would require a connection. Perhaps that, too, could be encoded in a (likely separate) QR code.

Profile Information

For casual conversation, a nickname in the profile data should be sufficient. Once a client interacts with someone, they can be added as a contact as a way of verifying the next conversation with someone with that username is actually the same person as before.

For situations where you want to verify an identity actually has a credentials they claim, you can query a nameserver that vouches for them. For example, whitehouse.gov would have a nameserver that specifies which identity is the actual president of the United States (and other government officials).

There could be nameservers that allow you to openly "register" your identity with them to get a unique human readable username you can include on billboards or other visual media where you want someone to be able to memorize the identifier, rather than scan a QR code or something.

For more details on how these decentralized usernames would work, check out Petnames.

Identity Recovery

If you lose access to your account, it's gone forever. That is why I think there should be defaults to backup your private key to existing reliable servers, even if they're owned by large corporations. Otherwise I would see someone have their phone stolen, lost, or upgraded and be surprised when their account is now inaccessible.

If you do lose your account and create a new identity, you could have others "vouch" for the new identity being an alias for the previous identity. You could verify your new identity with people IRL, and then other clients can see those vouches publicly and, after sufficient quantity, just implicitly assume they're the same (although with some sort of indicator, so if this gets abused, users are at least aware of the possibility of impersonation.

+ \ No newline at end of file diff --git a/garden/decentralized-moderation/index.html b/garden/decentralized-moderation/index.html index 6263be072..f389e5e11 100644 --- a/garden/decentralized-moderation/index.html +++ b/garden/decentralized-moderation/index.html @@ -6,14 +6,14 @@ Decentralized Moderation | The Paper Pilot - + - + - - - + + + @@ -53,9 +53,9 @@ -
Skip to content

Decentralized Moderation

661 words, ~4 minute read. Planted -.


Referenced by:"No Politics" RulesDecentralized Social MediaDigital LocalityFedi v2ModerationVirality
Tags:Decentralized

Naturally, this refers to how to properly Moderate content, typically within Social Media, in a Decentralized fashion - no central authority defining or enforcing the rules. This typically involves organizing under Anarchist principles.

Of course, the standard tools individuals are already familiar for self-moderating their content will still apply - muting or blocking people. This is not sufficient though, as it still means people would need to be exposed to the bad content before being able to block it, and it does nothing to combat the spread of misinformation.

For specifically tackling the problem of keeping fascism out of a community, I recommend this video (and the whole series) by Innuendo Studios.

Approaches

Labelers

ATProto designed a system of labelers that anyone can create and follow. Labeling services mark accounts or posts as NSFW, gore, etc. These will cause the post to either be hidden entirely or obscured until the user clicks through a warning. These labelers can be configured by the app designer or the user themselves. The labelers can be linked to reporting services or setup to label based on arbitrary criteria, such as sending each reported post to an LLM for judgement.

I have several concerns with this system. Firstly, these labelers are likely to accumulate influence as the popular ones get used more and thus become more popular. This centralizes power.

The second concern is with malicious labelers. If a labeler decides to create a list of people known to be a member of a specific marginalized community, there's little to no action anyone can do to stop it.

Lastly, this is moderation through the use of blocklists. This isn't inherently bad, but it's a double edged sword, as I discuss here).

Network of vouches

Identities could have a system by which they vouch for or against other identities that they are human and make content worth looking at, and clients could use this network of vouches to filter posts to display or retrieve. For example, a user may say they only want to see posts made by identities within a chain of 4 vouches to themselves. Upon account creation, users could be prompted to vouch for IRL friends or some popular figures within topics they care about to get started. In theory the longer the chain can be, the more varied the content a user will see, and the more likely for it to be something they disagree with. This would allow users to customize how narrow their feed is at a given time by just changing the max chain length. They can also continue vouching for more people to more precisely expand their feed.

Clients could include tools to analyze their network of vouches, such as displaying all the identities within certain max lengths, or viewing what chain was followed for a specific post to have been displayed. Clients could also add additional tools to customize the chain, like being able to ignore a specific user's vouches or reposts/reblogs. They could also treat any interaction as a vouch, overriding the max chain length for different contexts, such as when used for counting likes.

Specific entity types, such as one representing a reddit-like community, could display all replies rather than use the network of trust, and offer controls like only counting likes from within the network when sorting the replies.

This would essentially be an alternative to how current fediverse applications block entire instances as a heuristic, so they can get rid of undesirable content while minimizing how much of it they need to see before doing so. Except in this model, you can always reach people regardless of what server they decided to use, and the controls of in the hands of the individual.

Digital Locality

Similar to the network of vouches, a network with digital locality naturally limits the amount of content you'll see, essentially eliminating bots and spam as well as organically filtering the content you see based on the people you interact with.

- +
Skip to content

Decentralized Moderation

661 words, ~4 minute read. Planted +.


Referenced by:"No Politics" RulesDecentralized Social MediaDigital LocalityFedi v2ModerationVirality
Tags:Decentralized

Naturally, this refers to how to properly Moderate content, typically within Social Media, in a Decentralized fashion - no central authority defining or enforcing the rules. This typically involves organizing under Anarchist principles.

Of course, the standard tools individuals are already familiar for self-moderating their content will still apply - muting or blocking people. This is not sufficient though, as it still means people would need to be exposed to the bad content before being able to block it, and it does nothing to combat the spread of misinformation.

For specifically tackling the problem of keeping fascism out of a community, I recommend this video (and the whole series) by Innuendo Studios.

Approaches

Labelers

ATProto designed a system of labelers that anyone can create and follow. Labeling services mark accounts or posts as NSFW, gore, etc. These will cause the post to either be hidden entirely or obscured until the user clicks through a warning. These labelers can be configured by the app designer or the user themselves. The labelers can be linked to reporting services or setup to label based on arbitrary criteria, such as sending each reported post to an LLM for judgement.

I have several concerns with this system. Firstly, these labelers are likely to accumulate influence as the popular ones get used more and thus become more popular. This centralizes power.

The second concern is with malicious labelers. If a labeler decides to create a list of people known to be a member of a specific marginalized community, there's little to no action anyone can do to stop it.

Lastly, this is moderation through the use of blocklists. This isn't inherently bad, but it's a double edged sword, as I discuss here).

Network of vouches

Identities could have a system by which they vouch for or against other identities that they are human and make content worth looking at, and clients could use this network of vouches to filter posts to display or retrieve. For example, a user may say they only want to see posts made by identities within a chain of 4 vouches to themselves. Upon account creation, users could be prompted to vouch for IRL friends or some popular figures within topics they care about to get started. In theory the longer the chain can be, the more varied the content a user will see, and the more likely for it to be something they disagree with. This would allow users to customize how narrow their feed is at a given time by just changing the max chain length. They can also continue vouching for more people to more precisely expand their feed.

Clients could include tools to analyze their network of vouches, such as displaying all the identities within certain max lengths, or viewing what chain was followed for a specific post to have been displayed. Clients could also add additional tools to customize the chain, like being able to ignore a specific user's vouches or reposts/reblogs. They could also treat any interaction as a vouch, overriding the max chain length for different contexts, such as when used for counting likes.

Specific entity types, such as one representing a reddit-like community, could display all replies rather than use the network of trust, and offer controls like only counting likes from within the network when sorting the replies.

This would essentially be an alternative to how current fediverse applications block entire instances as a heuristic, so they can get rid of undesirable content while minimizing how much of it they need to see before doing so. Except in this model, you can always reach people regardless of what server they decided to use, and the controls of in the hands of the individual.

Digital Locality

Similar to the network of vouches, a network with digital locality naturally limits the amount of content you'll see, essentially eliminating bots and spam as well as organically filtering the content you see based on the people you interact with.

+ \ No newline at end of file diff --git a/garden/decentralized-social-media/index.html b/garden/decentralized-social-media/index.html index e6acbac6b..4967b37fd 100644 --- a/garden/decentralized-social-media/index.html +++ b/garden/decentralized-social-media/index.html @@ -6,14 +6,14 @@ Decentralized Social Media | The Paper Pilot - + - + - - - + + + @@ -53,9 +53,9 @@ -
Skip to content

Decentralized Social Media

25 words, ~0 minute read. Planted -.


Referenced by:ModerationNostrVirality

Social Media that is fully Decentralized (and not just Federated Social Media ). Such a network would require Decentralized Moderation and Decentralized Identity. The Agentic Fediverse strives to be a decentralized social media.

Nostr is the largest currently existing example of a fully decentralized social media.

- +
Skip to content

Decentralized Social Media

25 words, ~0 minute read. Planted +.


Referenced by:ModerationNostrVirality

Social Media that is fully Decentralized (and not just Federated Social Media ). Such a network would require Decentralized Moderation and Decentralized Identity. The Agentic Fediverse strives to be a decentralized social media.

Nostr is the largest currently existing example of a fully decentralized social media.

+ \ No newline at end of file diff --git a/garden/decentralized/index.html b/garden/decentralized/index.html index 549a2d4bb..81b46aedc 100644 --- a/garden/decentralized/index.html +++ b/garden/decentralized/index.html @@ -6,14 +6,14 @@ Decentralized | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Decentralized

225 words, ~1 minute read. Planted +

Skip to content

Decentralized

225 words, ~1 minute read. Planted . Last tended to -.


Referenced by:CommuneDecentralized ModerationDecentralized Social MediaDigital LocalityFedi v2MatrixSocial MediaVirality
Tagged by:Decentralized IdentityDecentralized ModerationNostr

Decentralized networks are networks with no central source of authority, all the way to the individual level. This provides many useful advantages to the user, such as data ownership, privacy, and increased agency over the rules you must follow and the client you use. This also means democratizing the service and helping protect it from Enshittification. There's not many examples of fully decentralized networks today, but some common examples are RSS, cryptocurrency, torrenting, and other peer-to-peer software. Some energy grids are decentralized, relying on individuals generating their own power and sharing surplus with neighbors.

An important caveat to the use of the term decentralization is that federated networks are often (erroneously) considered decentralized. Federated networks are ones where users have to join or create an entity, which is usually non-trivial, and will then be subject to the rules and limitations of that entity, but can theoretically then communicate with users who are members of other entities. Common examples are email and the Fediverse. The distinction is important because federations trend towards a handful of large entities, thus centralizing power still. This happens due to the difficulty in migrating between servers, creating a new server, and even just picking a specific server to join. There is work being done in creating a properly decentralized alternative to the fediverse called the Agentic Fediverse.

- +.


Referenced by:CommuneDecentralized ModerationDecentralized Social MediaDigital LocalityFedi v2MatrixSocial MediaVirality
Tagged by:Decentralized IdentityDecentralized ModerationNostr

Decentralized networks are networks with no central source of authority, all the way to the individual level. This provides many useful advantages to the user, such as data ownership, privacy, and increased agency over the rules you must follow and the client you use. This also means democratizing the service and helping protect it from Enshittification. There's not many examples of fully decentralized networks today, but some common examples are RSS, cryptocurrency, torrenting, and other peer-to-peer software. Some energy grids are decentralized, relying on individuals generating their own power and sharing surplus with neighbors.

An important caveat to the use of the term decentralization is that federated networks are often (erroneously) considered decentralized. Federated networks are ones where users have to join or create an entity, which is usually non-trivial, and will then be subject to the rules and limitations of that entity, but can theoretically then communicate with users who are members of other entities. Common examples are email and the Fediverse. The distinction is important because federations trend towards a handful of large entities, thus centralizing power still. This happens due to the difficulty in migrating between servers, creating a new server, and even just picking a specific server to join. There is work being done in creating a properly decentralized alternative to the fediverse called the Agentic Fediverse.

+ \ No newline at end of file diff --git a/garden/dice-armor/index.html b/garden/dice-armor/index.html index 4aae19230..55e75b970 100644 --- a/garden/dice-armor/index.html +++ b/garden/dice-armor/index.html @@ -6,14 +6,14 @@ Dice Armor | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Dice Armor

963 words, ~5 minute read. Planted +

Skip to content

Dice Armor

963 words, ~5 minute read. Planted . Last tended to -.


Referenced by:Babble Buds
Tags:My Projects

Download it here

Dice Armor is a game that started development as a semester-long project by a team of nine: a producer, a creative director, a narrative writer, an artist, two programmers, and 3 game designers. The information here is about my contributions as the lead programmer over the semester because I can show off stuff like the editor scripts I wrote. I was doing everything from interface coding, editor scripts, integrating Babble Buds, and of course, everything related to the gameplay itself. To date I'm still the lead programmer for the game; for more up-to-date information on the current state of the game please visit the official site.

The build available here was created for showing off at the end of the semester, and as such has some buttons present to make the game easier to skip parts of the game to see all the content: You start with all the dice in the game already in the shop, there's a button to give yourself free money to buy these dice with, and in the duel, there are buttons to force a win or a loss, which can be used to skip the tutorial (not recommended for first-time players).

Dice Armor is a dice dueling game. Players can use abilities, flip dice, and attack each other to win in a dice game that puts chance into the hands of the players. This is what the dueling scene looks like, with a tutorial cutscene happening on top to guide the player through the basics. Also, all the dice are constructed dynamically, using quaternion math to figure out the placement of each component relative to the face it is going on. The die in the middle has one of the player' and opponents' portraits on each of its sides.

For many of the objects I've created, I've made scriptable objects so that game designers can add and modify them easily. Additionally, I would create custom inspectors for the objects to help make them as easy to understand and edit as possible. The opponent's artificial intelligence is made up of many strategies, in a prioritized list. When it is the opponents' turn they go through each strategy and check if they can be run, and if so then the opponent performs the strategy and starts back over at the top of the list of strategies. The + sign under the list of strategies opens an organized dropdown of all the various strategies.

In addition to custom inspector code, I've created new tools for the editor for our game designers to use. This is a duel simulator that will take two opponents and simulate an arbitrary number of duels between them, and output the results and summarize them for you, much much quicker than manually going through the duels, even with an absurdly high timeScale. This will become incredibly useful in making balance changes and testing new dice against existing sets. This is a screenshot of it in edit mode, but in play mode it removes the "Dueling Managers" field and will use whatever the current duel balance settings are, allowing for the GDs to test freely in play mode without worrying about undoing all their changes afterward.

I created the Babble Buds puppet editor and ported the rendering library I wrote for it to C# so it could be used in Unity. Dice Armor has a full campaign using cutscenes made using the Babble Buds cutscene editor, taking advantage of its support for custom commands and fields to control things like talking, giving the player dice and money, starting duels, and controlling player progression through the story.

When a cutscene ends, its final command is to either start a duel or set the next cutscene in the story. In the latter case, there is an additional field for what to call the next cutscene, and what location it takes place. The cutscene is then added to the player's save file, and when they visit the city locations are greyed out until they have at least one action to do there. Each location has a dynamically populated action wheel with a custom range of acceptable angles.

The dice shop is dynamically populated by a list of dice available to the player, which can be changed during cutscenes, and is checked against the dice owned by the player to generate sold-out indicators. On the left, the player can choose to filter the options down to a single dice effect, which also updates the "Buy All" button to buy only all the dice in the current filter.

The inventory works most the same as the shop, but for equipping dice. It also allows you to drag individual dice or entire sets to the equipped dice glyph. While dragging it will highlight all the slots the new dice will be equipped into.

The dice rolling uses the physics engine and detects once the dice have stopped moving, then determines which side is face up based on which of the normals is closest to straight up. It flags the die as cocked if that smallest angle is above a threshold. The dice sink into the table when not rolling to not interfere with any dice that are rolling.

During certain events like winning the game or having the face of a die broken, the players' portraits will flash an emotion for a second. After winning, a random living die from the winning player is chosen to play their "finisher move", a flashy and dramatic effect to end the game. Shown is the arcane mechana's finisher, "Missile Storm".

After development stopped, the project became Open Source - check it out here

- +.


Referenced by:Babble Buds
Tags:My Projects

Download it here

Dice Armor is a game that started development as a semester-long project by a team of nine: a producer, a creative director, a narrative writer, an artist, two programmers, and 3 game designers. The information here is about my contributions as the lead programmer over the semester because I can show off stuff like the editor scripts I wrote. I was doing everything from interface coding, editor scripts, integrating Babble Buds, and of course, everything related to the gameplay itself. To date I'm still the lead programmer for the game; for more up-to-date information on the current state of the game please visit the official site.

The build available here was created for showing off at the end of the semester, and as such has some buttons present to make the game easier to skip parts of the game to see all the content: You start with all the dice in the game already in the shop, there's a button to give yourself free money to buy these dice with, and in the duel, there are buttons to force a win or a loss, which can be used to skip the tutorial (not recommended for first-time players).

Dice Armor is a dice dueling game. Players can use abilities, flip dice, and attack each other to win in a dice game that puts chance into the hands of the players. This is what the dueling scene looks like, with a tutorial cutscene happening on top to guide the player through the basics. Also, all the dice are constructed dynamically, using quaternion math to figure out the placement of each component relative to the face it is going on. The die in the middle has one of the player' and opponents' portraits on each of its sides.

For many of the objects I've created, I've made scriptable objects so that game designers can add and modify them easily. Additionally, I would create custom inspectors for the objects to help make them as easy to understand and edit as possible. The opponent's artificial intelligence is made up of many strategies, in a prioritized list. When it is the opponents' turn they go through each strategy and check if they can be run, and if so then the opponent performs the strategy and starts back over at the top of the list of strategies. The + sign under the list of strategies opens an organized dropdown of all the various strategies.

In addition to custom inspector code, I've created new tools for the editor for our game designers to use. This is a duel simulator that will take two opponents and simulate an arbitrary number of duels between them, and output the results and summarize them for you, much much quicker than manually going through the duels, even with an absurdly high timeScale. This will become incredibly useful in making balance changes and testing new dice against existing sets. This is a screenshot of it in edit mode, but in play mode it removes the "Dueling Managers" field and will use whatever the current duel balance settings are, allowing for the GDs to test freely in play mode without worrying about undoing all their changes afterward.

I created the Babble Buds puppet editor and ported the rendering library I wrote for it to C# so it could be used in Unity. Dice Armor has a full campaign using cutscenes made using the Babble Buds cutscene editor, taking advantage of its support for custom commands and fields to control things like talking, giving the player dice and money, starting duels, and controlling player progression through the story.

When a cutscene ends, its final command is to either start a duel or set the next cutscene in the story. In the latter case, there is an additional field for what to call the next cutscene, and what location it takes place. The cutscene is then added to the player's save file, and when they visit the city locations are greyed out until they have at least one action to do there. Each location has a dynamically populated action wheel with a custom range of acceptable angles.

The dice shop is dynamically populated by a list of dice available to the player, which can be changed during cutscenes, and is checked against the dice owned by the player to generate sold-out indicators. On the left, the player can choose to filter the options down to a single dice effect, which also updates the "Buy All" button to buy only all the dice in the current filter.

The inventory works most the same as the shop, but for equipping dice. It also allows you to drag individual dice or entire sets to the equipped dice glyph. While dragging it will highlight all the slots the new dice will be equipped into.

The dice rolling uses the physics engine and detects once the dice have stopped moving, then determines which side is face up based on which of the normals is closest to straight up. It flags the die as cocked if that smallest angle is above a threshold. The dice sink into the table when not rolling to not interfere with any dice that are rolling.

During certain events like winning the game or having the face of a die broken, the players' portraits will flash an emotion for a second. After winning, a random living die from the winning player is chosen to play their "finisher move", a flashy and dramatic effect to end the game. Shown is the arcane mechana's finisher, "Missile Storm".

After development stopped, the project became Open Source - check it out here

+ \ No newline at end of file diff --git a/garden/digital-gardens/index.html b/garden/digital-gardens/index.html index d97acf3ba..a9b52d971 100644 --- a/garden/digital-gardens/index.html +++ b/garden/digital-gardens/index.html @@ -6,14 +6,14 @@ Digital Gardens | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Digital Gardens

67 words, ~0 minute read. Planted +

Skip to content

Digital Gardens

67 words, ~0 minute read. Planted . Last tended to -.


Referenced by:ChronologicalCommuneDebateFilter BubblesGarden-RSSNetwork of KnowledgeOrchardThe Cozy WebThe Small WebThis Knowledge Hub

Digital Gardens are Freeform collections of information made by an individual or community

This Knowledge Hub is a digital garden

Collections of digital gardens and resources for creating them:

- +.


Referenced by:ChronologicalCommuneDebateFilter BubblesGarden-RSSNetwork of KnowledgeOrchardThe Cozy WebThe Small WebThis Knowledge Hub

Digital Gardens are Freeform collections of information made by an individual or community

This Knowledge Hub is a digital garden

Collections of digital gardens and resources for creating them:

+ \ No newline at end of file diff --git a/garden/digital-locality/index.html b/garden/digital-locality/index.html index 3a7f5f2c8..8c69c627b 100644 --- a/garden/digital-locality/index.html +++ b/garden/digital-locality/index.html @@ -6,14 +6,14 @@ Digital Locality | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Digital Locality

1803 words, ~10 minute read. Planted +

Skip to content

Digital Locality

1803 words, ~10 minute read. Planted . Last tended to -.


Referenced by:"No Politics" RulesChromatic LatticeDecentralized ModerationFilter BubblesSocial MediaVirality

A locality is a physical area or neighborhood where people live and regularly see each other. In the same way I believe strong Local Communities are highly important in real life, I think Social Media would benefit from having digital localities.

A digital locality will have a higher concentration of recognition between its members, leading to more meaningful relationships. This is achieved by operating similar to a physical neighborhood, where you're able to "look outside" and perhaps see a couple neighbors quite regularly, but with additional effort you can always "walk" further and further out to see a larger variety of people, and similarly others may "walk" to find you. This makes individual reach rely on a gradient of effort, keeping influence spread thin.

The motivations behind digital locality are aligned with the findings of Dunbar and his research on the cognitive limit for how many people we can maintain meaningful relationships with. He discusses his research and how it's held up over the years in this article.

Important Aspects

Porosity

The most important aspect of digital locality should be that one's neighborhood has no discrete walls, only continuous gradients. For example, if our goal was merely small communities where you see the same people regularly, any small discord server would fit the bill. But in discord if you want to reach out to "nearby" users, you have to join an entire new discord server. In other words, communities on discord are not "porous", letting users freely "leak" between each other. The neighborhood metaphor for digital locality would mean having no discrete walls around any community, thus being fully "porous". This allows you to more easily expand your network and meet people with whom to form meaningful relationships.

Decentralization

A large motivation behind this concept is spreading influence thin. In the same way digital locality directly opposes the centralization of influence in the hands of the few, it opposes all sorts of centralization. Centralized ownership and moderation over the network leaves it vulnerable to Enshittification and other problems. In practice, this means such a network should be Decentralized, ideally built on something like the Agentic Fediverse.

Social media must be moderated, which means a network with digital locality will need Decentralized Moderation. There's several approaches discussed there, but ultimately the way digital locality works should overall mean users are significantly less likely to see unwanted content from influencers, advertisers, bots, spammers, or those who wish them harm. Users won't need to worry about their post going viral leading to a very large and unexpected amount of attention, including negative attention, directed their way.

Democratized Virality

A network with digital locality would make individual people or posts have limited reach, and thus prevent those from "going viral". However, movements and ideas can still spread largely uninhibited, and even empower individuals to help spread the movement moreso than traditional social media. They can put more effort into being heard by moving further and further out through the network, whereas on traditional social media you can only hope the algorithm spreads your post.

Synchronous vs Asynchronous Interactions

Exactly how such a network looks and behaves will differ based on if it's going for synchronous vs asynchronous communication. Synchronous is the easier one, as that's essentially just a network of chat rooms with links to other chat rooms. Users explore the network through those links and just have realtime conversations with the people they find.

Asynchronous interactions are a bit trickier, and I'm not fully convinced on how it should work. It'll be important to work this out since that's how a lot of social media operates - any social media where you make posts, essentially. We'll go over a couple approaches to how it could work, keeping mind neither are perfect.

Local Feeds

Having a feed of posts that's just those you follow and the stuff they've liked or shared works fairly well and can be done today in most existing social media apps. However, seeing the exact post that has gone through a very long chain of shares to get to you means the author of that post may be receiving more attention than they desired. Additionally, this method may not have enough throughout if you read a lot of posts or don't follow active people.

The network of vouches approach to Decentralized Moderation sort of expands on this type of feed, giving the user content from longer following chains and much more control over who is let into the network. It's also auditable, unlike algorithmic feeds.

Communal wiki editing

A more radical approach would be treating social media more like communal wiki editing. That is, if engaging with a post was, rather than liking or sharing it, proposing edits to communal wiki pages it relates to. This would be a process of message gardening, and would likely help distributing corrections to articles, which typically spread much less far than the original incorrect information. It's for that reason I brought this idea up at the end of Filter Bubbles as a potential way to combat the spread of misinformation.

However, wiki editing requires a lot more effort than liking or sharing currently does. It's also not clear how this would preserve locality without making discrete communities. Commune is related to this idea but would have discrete communities (although with a bit of porosity through shared channels). Perhaps discrete communities could be avoided by allowing anyone to create pages, but then allow them to enter Anarchist collectives that manage the page together. Anyone (or perhaps those within a network of vouches) can comment or propose edits to it, and through that the information spreads to members and anyone else who follows that page.

Obstacles

The Network Effect

The biggest obstacle, as with any alternative social media, is the network effect. People want to be on a platform that's already popular, thus preserving the status quo. Social Media typically succeeds by enabling some new medium, like Twitter for microplogging, vine for videos (and later Snapchat once vine shut down), or Musically for lip syncing. The exceptions are existing platforms with large user bases expanding into one of those new mediums, like Instagram or Musically rebranding as Tiktok.

There's an issue here, though. I'm not describing a new medium here. The unique selling point is that by limiting influence accumulation and making it so you're more likely to see the same not-popular people regularly, we're actually fighting against part of what makes social media interesting for so many people: the concept of this meritocratic space where anyone can become a celebrity if they just make good enough content. That it could become a job, even, where they get paid a lot to make content and receive free stuff and other perks for doing so. This is the classic American Dream argument that American culture has already been conditioned into supporting. So success for this platform may hinge on convincing people becoming a social media influencer is not a good thing to strive for, both for how unhealthy the mindset is, and how unlikely it is for any individual to "make it". Needless to say, that's a very tall order.

Avoiding Filter Bubbles (or Echo Chambers)

An anticipated argument against what I'm describing here is that it would encourage the creation of filter bubbles. But I'd like to counter that argument by saying you're tackling the wrong issue, and that filter bubbles are typically innocuous and abolishing them would be actively harmful to marginalized communities. Indeed, I think digital locality would help fight against a lot of the root problems that are often attributes to echo chambers, as I describe on the Filter Bubbles page .

Influences

Webrings

Erlend discusses a similar concept to locality in his blog post Federated Webrings, which describes how the old internet would make frequent use of webrings to connect similar sites. This would effectively create digital neighbors and make both the site owner and visitors connect with the owners and visitors of the other sites in the webring. Although I think these webrings become a bit too large and centralized. I would've preferred to see them work more like cooperatives, with some form of democratic decision making.

Erlend's suggestion for bringing webrings back is through the use of communities using shared topic-specific rooms. For example, several rust game development libraries having a shared chatroom for discussing game development in general. This makes the communities more porous, so members can discover related people and communities.

I recommend reading through the rest of Erlend's writing and keeping up with their projects. They've done a lot in this sphere, both while working at discourse and since, and are leading the charge for designing and implementing the agentic fediverse.

IndieWeb

Personal websites form a fully decentralized social network called the indie web, which focuses on data ownership. However, it's quite small due to the technical and financial barriers to creating a website. Due to the lack of centralization or algorithms, sites spread primarily by being linked to by others. That brings it close to what I'm describing here, although without asynchronous chat I don't think it's quite what I'm looking for.

MUDs

What I'm describing is also a lot like a MUD, classic online games where players existed in a world of connected rooms, where they interacted via a command line interface, including local and global chat. If it were decentralized and people all had control over their own room, it would look a lot like what I am describing (but much nerdier and less modern). It's a big inspiration for a lot of these ideas.

Where to Start

There are so many competing protocols out there at the moment, and the network effect has made them all struggle to find a foothold. I don't think anything described in here would be the unique selling point to just immediately attract a large user base. With that in mind, I think the approach should be to make something thats with using for reasons other than social media, and attach the social media experiment to it. That can serve as a proof of concept to prove the ideas here work, although ideas that don't work to be iterated upon, and collect public interest in whatever the next step is.

With the above in mind, let me introduce Chromatic Lattice, an incremental game I've been designing that would need social features to work anyways. Specifically, it will have boards for each player, where the actual gameplay happens. These boards can be linked to publicly, so you can show off your boards. When a player is visiting someone else's board, their cursor will be visible to others there, and their will be local chat to just people on that page, a form of ambient copresence. These boards can be customized, including links to other boards. Thus locality is introduced - we now have synchronous chat rooms that every player has, and they can explore the network by jumping through these links. There are more details on the chromatic lattice page.

- +.


Referenced by:"No Politics" RulesChromatic LatticeDecentralized ModerationFilter BubblesSocial MediaVirality

A locality is a physical area or neighborhood where people live and regularly see each other. In the same way I believe strong Local Communities are highly important in real life, I think Social Media would benefit from having digital localities.

A digital locality will have a higher concentration of recognition between its members, leading to more meaningful relationships. This is achieved by operating similar to a physical neighborhood, where you're able to "look outside" and perhaps see a couple neighbors quite regularly, but with additional effort you can always "walk" further and further out to see a larger variety of people, and similarly others may "walk" to find you. This makes individual reach rely on a gradient of effort, keeping influence spread thin.

The motivations behind digital locality are aligned with the findings of Dunbar and his research on the cognitive limit for how many people we can maintain meaningful relationships with. He discusses his research and how it's held up over the years in this article.

Important Aspects

Porosity

The most important aspect of digital locality should be that one's neighborhood has no discrete walls, only continuous gradients. For example, if our goal was merely small communities where you see the same people regularly, any small discord server would fit the bill. But in discord if you want to reach out to "nearby" users, you have to join an entire new discord server. In other words, communities on discord are not "porous", letting users freely "leak" between each other. The neighborhood metaphor for digital locality would mean having no discrete walls around any community, thus being fully "porous". This allows you to more easily expand your network and meet people with whom to form meaningful relationships.

Decentralization

A large motivation behind this concept is spreading influence thin. In the same way digital locality directly opposes the centralization of influence in the hands of the few, it opposes all sorts of centralization. Centralized ownership and moderation over the network leaves it vulnerable to Enshittification and other problems. In practice, this means such a network should be Decentralized, ideally built on something like the Agentic Fediverse.

Social media must be moderated, which means a network with digital locality will need Decentralized Moderation. There's several approaches discussed there, but ultimately the way digital locality works should overall mean users are significantly less likely to see unwanted content from influencers, advertisers, bots, spammers, or those who wish them harm. Users won't need to worry about their post going viral leading to a very large and unexpected amount of attention, including negative attention, directed their way.

Democratized Virality

A network with digital locality would make individual people or posts have limited reach, and thus prevent those from "going viral". However, movements and ideas can still spread largely uninhibited, and even empower individuals to help spread the movement moreso than traditional social media. They can put more effort into being heard by moving further and further out through the network, whereas on traditional social media you can only hope the algorithm spreads your post.

Synchronous vs Asynchronous Interactions

Exactly how such a network looks and behaves will differ based on if it's going for synchronous vs asynchronous communication. Synchronous is the easier one, as that's essentially just a network of chat rooms with links to other chat rooms. Users explore the network through those links and just have realtime conversations with the people they find.

Asynchronous interactions are a bit trickier, and I'm not fully convinced on how it should work. It'll be important to work this out since that's how a lot of social media operates - any social media where you make posts, essentially. We'll go over a couple approaches to how it could work, keeping mind neither are perfect.

Local Feeds

Having a feed of posts that's just those you follow and the stuff they've liked or shared works fairly well and can be done today in most existing social media apps. However, seeing the exact post that has gone through a very long chain of shares to get to you means the author of that post may be receiving more attention than they desired. Additionally, this method may not have enough throughout if you read a lot of posts or don't follow active people.

The network of vouches approach to Decentralized Moderation sort of expands on this type of feed, giving the user content from longer following chains and much more control over who is let into the network. It's also auditable, unlike algorithmic feeds.

Communal wiki editing

A more radical approach would be treating social media more like communal wiki editing. That is, if engaging with a post was, rather than liking or sharing it, proposing edits to communal wiki pages it relates to. This would be a process of message gardening, and would likely help distributing corrections to articles, which typically spread much less far than the original incorrect information. It's for that reason I brought this idea up at the end of Filter Bubbles as a potential way to combat the spread of misinformation.

However, wiki editing requires a lot more effort than liking or sharing currently does. It's also not clear how this would preserve locality without making discrete communities. Commune is related to this idea but would have discrete communities (although with a bit of porosity through shared channels). Perhaps discrete communities could be avoided by allowing anyone to create pages, but then allow them to enter Anarchist collectives that manage the page together. Anyone (or perhaps those within a network of vouches) can comment or propose edits to it, and through that the information spreads to members and anyone else who follows that page.

Obstacles

The Network Effect

The biggest obstacle, as with any alternative social media, is the network effect. People want to be on a platform that's already popular, thus preserving the status quo. Social Media typically succeeds by enabling some new medium, like Twitter for microplogging, vine for videos (and later Snapchat once vine shut down), or Musically for lip syncing. The exceptions are existing platforms with large user bases expanding into one of those new mediums, like Instagram or Musically rebranding as Tiktok.

There's an issue here, though. I'm not describing a new medium here. The unique selling point is that by limiting influence accumulation and making it so you're more likely to see the same not-popular people regularly, we're actually fighting against part of what makes social media interesting for so many people: the concept of this meritocratic space where anyone can become a celebrity if they just make good enough content. That it could become a job, even, where they get paid a lot to make content and receive free stuff and other perks for doing so. This is the classic American Dream argument that American culture has already been conditioned into supporting. So success for this platform may hinge on convincing people becoming a social media influencer is not a good thing to strive for, both for how unhealthy the mindset is, and how unlikely it is for any individual to "make it". Needless to say, that's a very tall order.

Avoiding Filter Bubbles (or Echo Chambers)

An anticipated argument against what I'm describing here is that it would encourage the creation of filter bubbles. But I'd like to counter that argument by saying you're tackling the wrong issue, and that filter bubbles are typically innocuous and abolishing them would be actively harmful to marginalized communities. Indeed, I think digital locality would help fight against a lot of the root problems that are often attributes to echo chambers, as I describe on the Filter Bubbles page .

Influences

Webrings

Erlend discusses a similar concept to locality in his blog post Federated Webrings, which describes how the old internet would make frequent use of webrings to connect similar sites. This would effectively create digital neighbors and make both the site owner and visitors connect with the owners and visitors of the other sites in the webring. Although I think these webrings become a bit too large and centralized. I would've preferred to see them work more like cooperatives, with some form of democratic decision making.

Erlend's suggestion for bringing webrings back is through the use of communities using shared topic-specific rooms. For example, several rust game development libraries having a shared chatroom for discussing game development in general. This makes the communities more porous, so members can discover related people and communities.

I recommend reading through the rest of Erlend's writing and keeping up with their projects. They've done a lot in this sphere, both while working at discourse and since, and are leading the charge for designing and implementing the agentic fediverse.

IndieWeb

Personal websites form a fully decentralized social network called the indie web, which focuses on data ownership. However, it's quite small due to the technical and financial barriers to creating a website. Due to the lack of centralization or algorithms, sites spread primarily by being linked to by others. That brings it close to what I'm describing here, although without asynchronous chat I don't think it's quite what I'm looking for.

MUDs

What I'm describing is also a lot like a MUD, classic online games where players existed in a world of connected rooms, where they interacted via a command line interface, including local and global chat. If it were decentralized and people all had control over their own room, it would look a lot like what I am describing (but much nerdier and less modern). It's a big inspiration for a lot of these ideas.

Where to Start

There are so many competing protocols out there at the moment, and the network effect has made them all struggle to find a foothold. I don't think anything described in here would be the unique selling point to just immediately attract a large user base. With that in mind, I think the approach should be to make something thats with using for reasons other than social media, and attach the social media experiment to it. That can serve as a proof of concept to prove the ideas here work, although ideas that don't work to be iterated upon, and collect public interest in whatever the next step is.

With the above in mind, let me introduce Chromatic Lattice, an incremental game I've been designing that would need social features to work anyways. Specifically, it will have boards for each player, where the actual gameplay happens. These boards can be linked to publicly, so you can show off your boards. When a player is visiting someone else's board, their cursor will be visible to others there, and their will be local chat to just people on that page, a form of ambient copresence. These boards can be customized, including links to other boards. Thus locality is introduced - we now have synchronous chat rooms that every player has, and they can explore the network by jumping through these links. There are more details on the chromatic lattice page.

+ \ No newline at end of file diff --git a/garden/direct-democracy/index.html b/garden/direct-democracy/index.html index 6a250d8e9..c2c2239fb 100644 --- a/garden/direct-democracy/index.html +++ b/garden/direct-democracy/index.html @@ -6,14 +6,14 @@ Direct Democracy | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Direct Democracy

40 words, ~0 minute read. Planted +

Skip to content

Direct Democracy

40 words, ~0 minute read. Planted . Last tended to -.


Referenced by:AnarchismConsensus DemocracyGerrymandering

A form of democracy where every voter gets to vote on every issue directly, and the majority rules. This form of voting is often criticized for having no safe guards to prevent a majority group from oppressing a minority group.

- +.


Referenced by:AnarchismConsensus DemocracyGerrymandering

A form of democracy where every voter gets to vote on every issue directly, and the majority rules. This form of voting is often criticized for having no safe guards to prevent a majority group from oppressing a minority group.

+ \ No newline at end of file diff --git a/garden/enshittification/index.html b/garden/enshittification/index.html index 58483659b..dd5e99912 100644 --- a/garden/enshittification/index.html +++ b/garden/enshittification/index.html @@ -6,14 +6,14 @@ Enshittification | The Paper Pilot - + - + - - - + + + @@ -53,9 +53,9 @@ -
Skip to content

Enshittification

66 words, ~0 minute read. Planted -.


Referenced by:DecentralizedDigital LocalityThe Small Web

Large websites are expensive to operate and are typically owned by corporations. The profit motive of capitalism states that these websites must continuously be trying to make more money, which means if they're not growing users, they must increase how much they're making per user. This process means corporate backed websites become worse for their users over time, which Cory Doctorow coined as Enshittification.

- +
Skip to content

Enshittification

66 words, ~0 minute read. Planted +.


Referenced by:DecentralizedDigital LocalityThe Small Web

Large websites are expensive to operate and are typically owned by corporations. The profit motive of capitalism states that these websites must continuously be trying to make more money, which means if they're not growing users, they must increase how much they're making per user. This process means corporate backed websites become worse for their users over time, which Cory Doctorow coined as Enshittification.

+ \ No newline at end of file diff --git a/garden/everything-is-political/index.html b/garden/everything-is-political/index.html index cc323a738..b26bfdeaa 100644 --- a/garden/everything-is-political/index.html +++ b/garden/everything-is-political/index.html @@ -6,14 +6,14 @@ Everything is Political | The Paper Pilot - + - + - - - + + + @@ -53,9 +53,9 @@ -
Skip to content

Everything is Political

1100 words, ~6 minute read. Planted -.


Referenced by:"No Politics" Rules

Politics shape every facet of our lives, but its influence is often so entrenched it becomes invisible unless you're actively trying to be conscious of it. But being conscious of it is important, because otherwise you'll just end up implicitly supporting the current power structures created and maintained by the political status quo. Or society has guided us towards considering much of it as apolitical when is not for the purpose of perpetuating the existing power structures (capitalism, patriarchy, and white supremacy).

Consumption is political

We live in a society dictated by capitalism, and it has infiltrated not only our markets but every aspect of our lives. We all know when you buy an apple from the store not all of it goes to the workers; it's putting some amount of money in capitalists' pockets and further accumulating wealth at the top of the hierarchy. We know the prices are only as low as they are due to the exploitation of workers all around the world working in horrible conditions for horrible pay. We know the company we buy from is organized like a totalitarian regime where all the decisions come from up high and serve to benefit those at the top. So why isn't buying an apple political?

Engaging in our market economy is both a necessity for our survival, and normalized through decades and decades of propaganda and reinforcement of the status quo. We become alienated to the effects of our actions as a defense measure because our daily complicity in various atrocities are simply too grand to carry on our shoulders. It becomes apolitical out of necessity. This has a side effect of making all challenges to the status quo (progressivism) appear far more controversial and political than just keeping things as they are.

With so many things becoming commodified, this effect becomes stronger with time. Our culture, love, attention have all been commodified. Everything being for sale means politics affects everything.

The Search For The Apolitical Video Game goes over how essentially everything is political, through the framework of searching for an "apolitical" video game. The arguments they make for video games trivially apply to all forms of media. If all media is political, so is the act of consuming it. Even news will always have a bias, as Objectivity doesn't exist.

r/NonPoliticalTwitter

This is a subreddit that claims to only allow non-political content. Naturally, this is a good case study to argue why the concept of non-political content doesn't exist. They have an interesting interpretation of politics, wherein content can even involve political figures, if the focus of the post isn't considered political. This leads to one of the top posts at the time of writing being about Jimmy Carter giving a speech in Japan. So its a post about a US president engaging in politics abroad, but the post focuses on how an interpreter handled a joke, so it's not political. There's naturally no discussion on why Carter was in Japan or putting this event in a broader context of the relationship between the US and Japan after WW2 and Carter's role in repairing it.

Even when they don't involve US presidents, nearly every post on that subreddit can be associated with politics. Complaining about subscription costs and how support agents can reduce the prices to keep you from leaving is apolitical, as is discussing how childrens cereal is so unhealthy ants disregard it as food. Apparently criticizing the lies told to us by our education system is apolitical, just like voicing distaste with how much advertising corporations spam. These are political issues, and they're only able to pass as apolitical by maintaining a lack of awareness on how politics shape society.

Inaction is political

There is no "apolitical" perspective, as that's really just the stance of maintaining the political status quo. As put by Angela Davis, "In a racist society it is not enough to be non-racist, we must be anti-racist." Essentially, politics affect all of us and everything is political, and if you believe politics don't effect you, that's probably because the current political and economic systems work in your favor.

How to radicalize a normie describes how communities can be overtaken by fascists exploiting the fact that statements that are deemed "apolitical" are the ones with consensus, coupled with the fact that progressive statements, by challenging the status quo, are not going to have consensus in communities without a political alignment.

Centrism has no merit

Adjacent to people seeking to avoid politics outright are those who hold the belief that our two parties are on polar extremes and hold the belief the correct position is going to be somewhere in the middle, taking aspects of both parties. This is fallacious because the center has no special value that makes it better than the extremes, a lot of the issues centrists want to pull from the different parties never needed to be politicized in the first place, and the two US parties are not on polar extremes anyways.

The center is just the midpoint between two points. That's it. Rejecting both sides doesn't make you intellectually or morally superior. The horseshoe theory was never a good theory to begin with, with the underlying political philosophies between the two sides being fundamentally opposed. I recommend "Blackshirts and Reds" by Michael Parenti if you'd like a better understanding of why the two ideologies are polar opposites, and how they clashed.

In practice these midpoints don't even make much sense to uphold. If the left says trans people should not be discriminated against, and the right says they shouldn't exist, where's the midpoint? We should discriminate against trans people but allow them to exist? Oh, how kind. In practice this is literally the stance liberals take, though: trans people can exist, but how dare you support Trans athletes in sports!

Today, centrism in America is not even talking about the midpoint between the rightist and leftist ideologies, but rather the Republicans and Democrats. These are arbitrary points dictated by the Overton Window that make the midpoint even more arbitrary. What is the midpoint between socialism and capitalism? The former is defined by private property not existing, the latter the opposite. Any midpoint is clearly still just capitalism, just with some regulations to temporarily stave off crises caused by capitalism's contradictions. The two US parties are both in defense of private ownership of the means of production, so the midpoint was never really going to be anywhere close to the left. This is why Bernie Sanders was called a "true" centrist because, by being further left than the Democrats, he actually was closer to whatever the actual midpoint between the far left and far right would be. Even then, the other arguments against centrism still apply.

Like political apathy, centrism is really just a bias towards the status quo, which I shall remind you is shaped by unjust power structures like capitalism, patriarchy, and white supremacy. All my arguments, both here and in my page against "No Politics" Rules, apply equally to centrists as they do the politically apathetic. The Angela Davis quote once again comes to mind: "In a racist society it is not enough to be non-racist, we must be anti-racist."

- +
Skip to content

Everything is Political

1100 words, ~6 minute read. Planted +.


Referenced by:"No Politics" Rules

Politics shape every facet of our lives, but its influence is often so entrenched it becomes invisible unless you're actively trying to be conscious of it. But being conscious of it is important, because otherwise you'll just end up implicitly supporting the current power structures created and maintained by the political status quo. Or society has guided us towards considering much of it as apolitical when is not for the purpose of perpetuating the existing power structures (capitalism, patriarchy, and white supremacy).

Consumption is political

We live in a society dictated by capitalism, and it has infiltrated not only our markets but every aspect of our lives. We all know when you buy an apple from the store not all of it goes to the workers; it's putting some amount of money in capitalists' pockets and further accumulating wealth at the top of the hierarchy. We know the prices are only as low as they are due to the exploitation of workers all around the world working in horrible conditions for horrible pay. We know the company we buy from is organized like a totalitarian regime where all the decisions come from up high and serve to benefit those at the top. So why isn't buying an apple political?

Engaging in our market economy is both a necessity for our survival, and normalized through decades and decades of propaganda and reinforcement of the status quo. We become alienated to the effects of our actions as a defense measure because our daily complicity in various atrocities are simply too grand to carry on our shoulders. It becomes apolitical out of necessity. This has a side effect of making all challenges to the status quo (progressivism) appear far more controversial and political than just keeping things as they are.

With so many things becoming commodified, this effect becomes stronger with time. Our culture, love, attention have all been commodified. Everything being for sale means politics affects everything.

The Search For The Apolitical Video Game goes over how essentially everything is political, through the framework of searching for an "apolitical" video game. The arguments they make for video games trivially apply to all forms of media. If all media is political, so is the act of consuming it. Even news will always have a bias, as Objectivity doesn't exist.

r/NonPoliticalTwitter

This is a subreddit that claims to only allow non-political content. Naturally, this is a good case study to argue why the concept of non-political content doesn't exist. They have an interesting interpretation of politics, wherein content can even involve political figures, if the focus of the post isn't considered political. This leads to one of the top posts at the time of writing being about Jimmy Carter giving a speech in Japan. So its a post about a US president engaging in politics abroad, but the post focuses on how an interpreter handled a joke, so it's not political. There's naturally no discussion on why Carter was in Japan or putting this event in a broader context of the relationship between the US and Japan after WW2 and Carter's role in repairing it.

Even when they don't involve US presidents, nearly every post on that subreddit can be associated with politics. Complaining about subscription costs and how support agents can reduce the prices to keep you from leaving is apolitical, as is discussing how childrens cereal is so unhealthy ants disregard it as food. Apparently criticizing the lies told to us by our education system is apolitical, just like voicing distaste with how much advertising corporations spam. These are political issues, and they're only able to pass as apolitical by maintaining a lack of awareness on how politics shape society.

Inaction is political

There is no "apolitical" perspective, as that's really just the stance of maintaining the political status quo. As put by Angela Davis, "In a racist society it is not enough to be non-racist, we must be anti-racist." Essentially, politics affect all of us and everything is political, and if you believe politics don't effect you, that's probably because the current political and economic systems work in your favor.

How to radicalize a normie describes how communities can be overtaken by fascists exploiting the fact that statements that are deemed "apolitical" are the ones with consensus, coupled with the fact that progressive statements, by challenging the status quo, are not going to have consensus in communities without a political alignment.

Centrism has no merit

Adjacent to people seeking to avoid politics outright are those who hold the belief that our two parties are on polar extremes and hold the belief the correct position is going to be somewhere in the middle, taking aspects of both parties. This is fallacious because the center has no special value that makes it better than the extremes, a lot of the issues centrists want to pull from the different parties never needed to be politicized in the first place, and the two US parties are not on polar extremes anyways.

The center is just the midpoint between two points. That's it. Rejecting both sides doesn't make you intellectually or morally superior. The horseshoe theory was never a good theory to begin with, with the underlying political philosophies between the two sides being fundamentally opposed. I recommend "Blackshirts and Reds" by Michael Parenti if you'd like a better understanding of why the two ideologies are polar opposites, and how they clashed.

In practice these midpoints don't even make much sense to uphold. If the left says trans people should not be discriminated against, and the right says they shouldn't exist, where's the midpoint? We should discriminate against trans people but allow them to exist? Oh, how kind. In practice this is literally the stance liberals take, though: trans people can exist, but how dare you support Trans athletes in sports!

Today, centrism in America is not even talking about the midpoint between the rightist and leftist ideologies, but rather the Republicans and Democrats. These are arbitrary points dictated by the Overton Window that make the midpoint even more arbitrary. What is the midpoint between socialism and capitalism? The former is defined by private property not existing, the latter the opposite. Any midpoint is clearly still just capitalism, just with some regulations to temporarily stave off crises caused by capitalism's contradictions. The two US parties are both in defense of private ownership of the means of production, so the midpoint was never really going to be anywhere close to the left. This is why Bernie Sanders was called a "true" centrist because, by being further left than the Democrats, he actually was closer to whatever the actual midpoint between the far left and far right would be. Even then, the other arguments against centrism still apply.

Like political apathy, centrism is really just a bias towards the status quo, which I shall remind you is shaped by unjust power structures like capitalism, patriarchy, and white supremacy. All my arguments, both here and in my page against "No Politics" Rules, apply equally to centrists as they do the politically apathetic. The Angela Davis quote once again comes to mind: "In a racist society it is not enough to be non-racist, we must be anti-racist."

+ \ No newline at end of file diff --git a/garden/fedi-v2/index.html b/garden/fedi-v2/index.html index b7cc76871..d4fddd5d0 100644 --- a/garden/fedi-v2/index.html +++ b/garden/fedi-v2/index.html @@ -6,14 +6,14 @@ Fedi v2 | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Fedi v2

3033 words, ~17 minute read. Planted +

Skip to content

Fedi v2

3033 words, ~17 minute read. Planted . Last tended to -.


Referenced by:Chromatic LatticeDecentralized Social MediaDecentralizedDigital LocalityFilter BubblesIncremental Social/nowOrchardSocial MediaThe IndieWeb/Signature BlocksWeird

A placeholder name for a theoretical new federated network that is client-centric, in contrast to the server-centric Fediverse. Many of the ideas here will be implemented as described or similarly by people much smarter than me as part of Agentic Federation on Iroh, an initiative by the Weird developers.

Motivation

The current fediverse, while in theory fully Decentralized, in practice suffers many of the issues associated with centralization. This is primarily caused by the friction of having to pick a server and the non feasibility of individuals buying a domain and setting up a single user instance - both of these causes lead to a handful of large servers with the bulk of the users. You can see this in action by looking up the relative sizes of lemmy and mastodon instances. Single-user Mastodon Instance is a Bad Idea goes over the non feasibility of self hosting and how it contributes to a handful of servers having the majority of the users.

The promise of federation is the ability to interact with the whole network, while being able to fully choose and customize how you yourself interact with the network. In practice though, clients are severely limited to what they can do based on the server software. Of particular note, Lemmy and Mastodon show content in different formats (threads vs microblogs), and no clients allow changing how they're displayed, or respecting the format of the source of the content. Clients also are unable to change sorting algorithms or how downvotes are handled - those are all dependent on the server. A Plan for Social Media - Rethinking Federation similarly criticizes how much of the decisions are dependent on the server, which most people won't be able to or willing to self host.

The pick a server problem is such a problem because not only do you have to pick what server has moderation policies you align with, but that you're also linking your identity with that server. Smaller servers tend to be more focused or niche, which is unlikely to fully encompass any person's entire identity. Why would I confine myself to being thepaperpilot@writinglovers.com if I'm more than a writing lover? Additionally, I'm risking that the community at that instance won't grow away from things I want to associate with, such as fascism or crypto. My identity could end up being associated with things I drastically don't want it to be.

Nostr fixes the pick a server problem with a properly decentralized identity, however it's done so by associating itself with crypto and the alt right, and fixing that culture problem is more effort than it's worth. It'll be difficult to gain broad adoption as anyone using the platform will have to take care to explain how they're using nostr but aren't alt right.

ATProto by bluesky offers a version of federation built for a handful of large instances, but allowing smaller servers to be spun up that can implement custom sorting algorithms, views, etc. Your identity can be tied to a domain you own, if you have one. This fixes a couple of the problems where you're unable to change certain things dictated by the servers, but doesn't quite go far enough. Their PDS system is very similar to what we're going for, but it's still tied to signing up at (and then relying upon) specific servers.

NextGraph looks very similar to what we're trying to build. My only note is really that it gives a bit of a crypto vibe through decisions like calling identities "wallets" that I think may make it fall into the same problems nostr has, but conceptually its really similar to everything discussed here, which is great! It should be incredibly easy to interoperate, at the very least.

Decentralized Identity

The decentralized fediverse should have a fully decentralized identity, where it's completely attached to the client rather than any server(s). This means you don't have to pick a server, worry about your chosen server going down, or that your identity will become associated with an undesired community. It can properly allow you to engage in your variety of interests without having to associate your identity with just one.

By relying on signed messages, content (posts, profile information, etc.) is also not attached to any specific delivery system. Relay servers, a USB stick, or QR code could all work and still have the guarantees it was written by someone with the private key and has not been tampered with. It should be noted that none of the major social media platforms existing today can give verifiable proof a message was not tampered with.

Servers

Servers would act as mere relays, whose job it is is to store messages and send them to any other clients or servers that have requested to hear about any new messages. Some relays may also display these messages in a web interface, so that you can still share links to messages online. Because your identity isn't attached to any specific server, you could send your messages out to any servers you wish, and change that list as often as you'd like. It's extremely resilient to individual servers going down.

If you want a private network, say for a school or job, you could setup a relay server that requires some sort of password when sending them messages, and then have that server not federate with the rest of the fediverse.

Servers would give clients ways to subscribe to subsets of all received messages - e.g. all messages, all messages from a specific user, any replies to messages from a specific user, or "shallow" subscriptions to a message, meaning it'll send you only 1 level of replies to that message.

With a decentralized identity and the ability to switch servers seamlessly whenever you want, many of the benefits of self hosting a server are granted to everyone. This means there'll likely be fewer servers than the current fediverse has. There'll likely be enough to ensure redundancy, but beyond that I'd really only expect a couple large servers, similar to how bluesky intends AtProto to have, and perhaps smaller instances by institutions that want to provide storage for the people within that institution. Fortunately, it also means the disadvantages of only having 1 or a small number of servers also go away. We only need enough instances for redundancy, but beyond that we don't need to worry about being locked into a server or your server having rules you disagree with or anything. You'll always have your data, and can just send it to another server whenever you'd like. These fewer but larger servers will be useful for discoverability with less traffic between all the servers.

Content

The protocol should be fairly content agnostic, and allow arbitrary metadata on messages that can be used by the community to come up with their own new forms of content to transmit over the protocol. For example, perhaps there's a body field that could include arbitrary text or binary data, and for binary data another field could clarify if its audio, video, an image, or something else.

The signature of the message acts as the de facto ID of that message, for replying purposes. Edits and reactions would be handled by "replying" to a message with a metadata flag indicating what the message actually represents. Edit messages should typically be ignored if they're not from the same author as the original message. We should assume some servers will always make an edit history fully public. Reactions should just be replies without any actual body, and a tag for what the reaction is - either binary image data or a code representing an emoji, like "+1" or "laughing". Upvotes and downvotes could be implemented via reactions.

Edit replies could be sent by people other than the original poster as well. Perhaps some clients would trust edits from a list of identities, but the original poster could also reply to an edit message with an "accepted" message as a form of officially accepting/endorsing that edit suggestion. Clients could also potentially include a list of "proposed edits" that haven't been accepted.

Groups/communities could also be specially flagged messages, effectively allowing for subreddit-style content. Posting to the community is just replying to the message. Subscribing to that community is just subscribing to that message. The original message creator can send edits to update stuff like the description of the community. Perhaps they can also send a message detailing other identities to trust for editing or moderating the community.

A bot could fairly easily be setup to make IndieWeb posts and web mentions use this protocol. Indeed, this protocol is very POSSE-friendly because you could have your original content on the website, and the messages can be spread across the network while allowing clients to verify it was untampered with and definitely came from that website. I plan on writing a proposal for IndieWeb posts to include The IndieWeb/Signature Blocks to enable this. Within this framework, Fedi v2 would not just be a other social media silo. It would be the source of truth, fully controlled by the author. Even if the author cross posts to other social media (silos), we'd effectively still be the original copy.

Decentralized Moderation

Success

I believe the main benefits of this new fediverse are mostly going to apply to the techy power users who will appreciate the increased control over their identity and browsing experience. As far as the general public goes, I think the main benefit will be verified authorship and guaranteeing lack of tampering. Specifically, I think this will appeal to notable figures who have to be wary of concerns like that. Reddit and Twitter could edit your content or stifle it in the algorithm, or any other sort of malicious actions. So I think success of this platform will mostly come from seeing notable figures switching to it, and treating is as the source of truth (even if they cross post it to other platforms for increased outreach). Ideally, they even host their messages on their own website.

Component Definitions

The agentic fediverse is currently being designed such that messages are entities in a Entity-Component relationship. Component schemas can then be formally defined and then implemented in clients, without the need of a centralized authority releasing formal spec bumps. In theory anyone could propose a new schema.

Here's some initial ideas for components I currently plan on proposing and perhaps even implementing:

  • Community (placeholder name): Marks that replies to this message should be displayed like a collection of threads, reddit-style.
  • Delete: Marks that this message is a deletion request to the message its a reply to.
    • Can be used to delete specific components in the parent message.
  • Edit: Marks that this message is an edit request to the message its a reply to.
    • Can be used to edit specific components in the parent message.
  • Accept: Marks that any requests in the message this message is a reply to were accepted.
    • Takes an optional schema property to identify which specific request component of the parent message was accepted.
  • Reaction: Marks that this message is a reaction to the message its a reply to.
  • Ascii: Describes a text component to be rendered.
  • Unicode: Describes a text component to be rendered.
  • Image: Describes an image component to be rendered. (Or perhaps specific file formats should have their own schemas)
  • Audio: Describes an audio component to be rendered. (Or perhaps specific file formats should have their own schemas)
  • Video: Describes a video component to be rendered. (Or perhaps specific file formats should have their own schemas)
  • Topics: Describes a list of topics/tags this message is relevant to, for use in client searching and filtering.
  • Editors: Describes a list of identities who have the power to edit this message, or accept edit requests to this message.
  • Deleters: Describes a list of identities who have the power to delete this message, or accept deletion requests to this message.
  • No Discovery: Marks that this message should not be included in any global feeds or search results. Servers should only send it to servers and clients that subscribe to messages like this one.
  • Timestamp Requested: Marks that this message would like to receive a response from a trusted server (optionally defined in the component data) once it is delivered. May also include a schema ID that represents what the timestamp represents. Defaults to referring to the published date.
  • Calendar Event: Describes a calendar event.
  • RSVP: Marks that you [are, might be, or aren't] participating in whatever a linked entity is describing.

Chatting

The agentic fediverse could theoretically also implement chat rooms, bringing advantages (like divorcing identity from servers) that current decentralized chat protocols like matrix don't offer.

Here are some of the components that could be used to represent a chat room:

  • Chat room: Marks that replies to this message should be shown as messages in a chat room.
  • Bridge: Marks that this identity is a bridge for an account on another service. Implies that the verification of authorship may not be preserved.

Games

The agentic fediverse could support sharing games using a Game component that includes a url or raw html required to play a game. In theory they could even support "cloud saves" by signing a message of their save data that only they can decrypt and sending it as a reply to the game message. Clients could handle displaying the game alongside the usual filtering and sorting features.

I'd also be excited in seeing a sort of MMO style game on the agentic fediverse. So you see other players and there's a shared game state, calculated on the client based on the actions recorded by the various different players. And since the rules would have to be defined by the components, people could create their own copies of the world (e.g. to play with a friend group or solo), or even make their own mods of the game. I'd like to look into that. I'll perhaps rethink Chromatic Lattice to work on such a framework, although it may be too complicated for this idea.

Having the game state be calculatable by the client like that would also allow trophies and achievements to work verifiably. People could probably still write software to copy someone else's events at the right times and effectively replicate their save, but I think that won't happen commonly enough to matter.

Permissions

Instead of having various different licenses like CC0, MIT, etc., just make each permission discrete. For example, you can have a DoNotTrainOn component that marks that using an entity for training AI models is not allowed.

This is different from the willow permissions system which determines who can read or write to specific entities/paths. This is for telling someone who has read access to your post what they're allowed to use it for.

There should be a component that makes permissions explicit rather than implicit. E.g. assume you don't have the right to do anything unless explicitly stated.

Local identity and contact management

If I have multiple apps that use the agentic fediverse (e.g. one for reddit like content, one for Twitter, discord, Google drive, etc.), I'd like to easily have them all use the same identity(s), as well as a shared contact list (so I know the person I saw do something on one app is the same as the person that did something on another app).

To that end, there should be an app/program that manages your identities and contacts on that device. It sets up your initial identity, any cloud backups, etc., and the other apps talk to it as needed. That could be sending it individual messages to sign or asking for a key that can be used to do limited functionality.

Contacts could be signed such that they're only readable by us, and then sent over the network so I can have multiple devices that keep their contact list synced between them

An identity management app could also work as a link handler for the leaf protocol. It could take a schema ID as another path component, which then describes the purpose of the URI and the expected remaining data in the URI. The identity management app can then pass the message along to any app that has specified it knows how to handle that schema.

Sustainability

Servers are expensive, especially as they get popular. Most current fediverse instances are free and funded by donations. Things like ads or paying for an account are difficult to do due to the nature of federation. This is a pretty major problem because if a server becomes too expensive to host, it will shut down, along with all the accounts associated with it. Fedi v2 makes individual servers going down not be an issue anymore, since identities aren't attached to them. However, it's an issue if all the instances go down, and if there's no way to pay for them still, why would any instance stay up?

Since instance nodes do not have to do filtering, sorting, or really any other processing, but rather just serving the events and sending out notifications to clients, the cost will be cheaper than the current fediverse. It's really just a file server, which is cheap. For example, idrive charges $40 per tb per year, which is enough for a LOT of content. So I expect some instance nodes to have fairly generous free tiers that will suffice for a lot of users. Idrive also doesn't have egress charges, so the cost only scales with how much content is being published, not downloaded.

For power users, instance nodes could accept payments to store data above the free quota. This would likely most often happen for people wishing to upload high resolution images or videos. A user could also switch nodes after filling a quota on one node - you don't have to delete your content on the old instance. You could also do this to backup your content on multiple nodes (although you should also keep a local copy of all your content).

I assume this aspect of Fedi v2 will be the most controversial - people really like free services, and are expecting it. Knowing they might eventually need to pay to post more will perhaps require a cultural shift. I think it's worth it to not have ads or tracking, and in general we should be supporting sustainable services.

What about Incremental Social?

I think Incremental Social can operate similarly to weird.one, hosting an iroh node and storing events for the agentic fediverse for users of the site. We'll generate and manage a keypair for the user, with the possibility of the user migrating their identity.

I suspect the way the identity management app will work to support sites like weird.one and incremental.social is by passing the request for a delegate key to incremental.social, which will then show the consent screen before passing the key back to the app which sends it to the actual fediverse app.

- +.


Referenced by:Chromatic LatticeDecentralized Social MediaDecentralizedDigital LocalityFilter BubblesIncremental Social/nowOrchardSocial MediaThe IndieWeb/Signature BlocksWeird

A placeholder name for a theoretical new federated network that is client-centric, in contrast to the server-centric Fediverse. Many of the ideas here will be implemented as described or similarly by people much smarter than me as part of Agentic Federation on Iroh, an initiative by the Weird developers.

Motivation

The current fediverse, while in theory fully Decentralized, in practice suffers many of the issues associated with centralization. This is primarily caused by the friction of having to pick a server and the non feasibility of individuals buying a domain and setting up a single user instance - both of these causes lead to a handful of large servers with the bulk of the users. You can see this in action by looking up the relative sizes of lemmy and mastodon instances. Single-user Mastodon Instance is a Bad Idea goes over the non feasibility of self hosting and how it contributes to a handful of servers having the majority of the users.

The promise of federation is the ability to interact with the whole network, while being able to fully choose and customize how you yourself interact with the network. In practice though, clients are severely limited to what they can do based on the server software. Of particular note, Lemmy and Mastodon show content in different formats (threads vs microblogs), and no clients allow changing how they're displayed, or respecting the format of the source of the content. Clients also are unable to change sorting algorithms or how downvotes are handled - those are all dependent on the server. A Plan for Social Media - Rethinking Federation similarly criticizes how much of the decisions are dependent on the server, which most people won't be able to or willing to self host.

The pick a server problem is such a problem because not only do you have to pick what server has moderation policies you align with, but that you're also linking your identity with that server. Smaller servers tend to be more focused or niche, which is unlikely to fully encompass any person's entire identity. Why would I confine myself to being thepaperpilot@writinglovers.com if I'm more than a writing lover? Additionally, I'm risking that the community at that instance won't grow away from things I want to associate with, such as fascism or crypto. My identity could end up being associated with things I drastically don't want it to be.

Nostr fixes the pick a server problem with a properly decentralized identity, however it's done so by associating itself with crypto and the alt right, and fixing that culture problem is more effort than it's worth. It'll be difficult to gain broad adoption as anyone using the platform will have to take care to explain how they're using nostr but aren't alt right.

ATProto by bluesky offers a version of federation built for a handful of large instances, but allowing smaller servers to be spun up that can implement custom sorting algorithms, views, etc. Your identity can be tied to a domain you own, if you have one. This fixes a couple of the problems where you're unable to change certain things dictated by the servers, but doesn't quite go far enough. Their PDS system is very similar to what we're going for, but it's still tied to signing up at (and then relying upon) specific servers.

NextGraph looks very similar to what we're trying to build. My only note is really that it gives a bit of a crypto vibe through decisions like calling identities "wallets" that I think may make it fall into the same problems nostr has, but conceptually its really similar to everything discussed here, which is great! It should be incredibly easy to interoperate, at the very least.

Decentralized Identity

The decentralized fediverse should have a fully decentralized identity, where it's completely attached to the client rather than any server(s). This means you don't have to pick a server, worry about your chosen server going down, or that your identity will become associated with an undesired community. It can properly allow you to engage in your variety of interests without having to associate your identity with just one.

By relying on signed messages, content (posts, profile information, etc.) is also not attached to any specific delivery system. Relay servers, a USB stick, or QR code could all work and still have the guarantees it was written by someone with the private key and has not been tampered with. It should be noted that none of the major social media platforms existing today can give verifiable proof a message was not tampered with.

Servers

Servers would act as mere relays, whose job it is is to store messages and send them to any other clients or servers that have requested to hear about any new messages. Some relays may also display these messages in a web interface, so that you can still share links to messages online. Because your identity isn't attached to any specific server, you could send your messages out to any servers you wish, and change that list as often as you'd like. It's extremely resilient to individual servers going down.

If you want a private network, say for a school or job, you could setup a relay server that requires some sort of password when sending them messages, and then have that server not federate with the rest of the fediverse.

Servers would give clients ways to subscribe to subsets of all received messages - e.g. all messages, all messages from a specific user, any replies to messages from a specific user, or "shallow" subscriptions to a message, meaning it'll send you only 1 level of replies to that message.

With a decentralized identity and the ability to switch servers seamlessly whenever you want, many of the benefits of self hosting a server are granted to everyone. This means there'll likely be fewer servers than the current fediverse has. There'll likely be enough to ensure redundancy, but beyond that I'd really only expect a couple large servers, similar to how bluesky intends AtProto to have, and perhaps smaller instances by institutions that want to provide storage for the people within that institution. Fortunately, it also means the disadvantages of only having 1 or a small number of servers also go away. We only need enough instances for redundancy, but beyond that we don't need to worry about being locked into a server or your server having rules you disagree with or anything. You'll always have your data, and can just send it to another server whenever you'd like. These fewer but larger servers will be useful for discoverability with less traffic between all the servers.

Content

The protocol should be fairly content agnostic, and allow arbitrary metadata on messages that can be used by the community to come up with their own new forms of content to transmit over the protocol. For example, perhaps there's a body field that could include arbitrary text or binary data, and for binary data another field could clarify if its audio, video, an image, or something else.

The signature of the message acts as the de facto ID of that message, for replying purposes. Edits and reactions would be handled by "replying" to a message with a metadata flag indicating what the message actually represents. Edit messages should typically be ignored if they're not from the same author as the original message. We should assume some servers will always make an edit history fully public. Reactions should just be replies without any actual body, and a tag for what the reaction is - either binary image data or a code representing an emoji, like "+1" or "laughing". Upvotes and downvotes could be implemented via reactions.

Edit replies could be sent by people other than the original poster as well. Perhaps some clients would trust edits from a list of identities, but the original poster could also reply to an edit message with an "accepted" message as a form of officially accepting/endorsing that edit suggestion. Clients could also potentially include a list of "proposed edits" that haven't been accepted.

Groups/communities could also be specially flagged messages, effectively allowing for subreddit-style content. Posting to the community is just replying to the message. Subscribing to that community is just subscribing to that message. The original message creator can send edits to update stuff like the description of the community. Perhaps they can also send a message detailing other identities to trust for editing or moderating the community.

A bot could fairly easily be setup to make IndieWeb posts and web mentions use this protocol. Indeed, this protocol is very POSSE-friendly because you could have your original content on the website, and the messages can be spread across the network while allowing clients to verify it was untampered with and definitely came from that website. I plan on writing a proposal for IndieWeb posts to include The IndieWeb/Signature Blocks to enable this. Within this framework, Fedi v2 would not just be a other social media silo. It would be the source of truth, fully controlled by the author. Even if the author cross posts to other social media (silos), we'd effectively still be the original copy.

Decentralized Moderation

Success

I believe the main benefits of this new fediverse are mostly going to apply to the techy power users who will appreciate the increased control over their identity and browsing experience. As far as the general public goes, I think the main benefit will be verified authorship and guaranteeing lack of tampering. Specifically, I think this will appeal to notable figures who have to be wary of concerns like that. Reddit and Twitter could edit your content or stifle it in the algorithm, or any other sort of malicious actions. So I think success of this platform will mostly come from seeing notable figures switching to it, and treating is as the source of truth (even if they cross post it to other platforms for increased outreach). Ideally, they even host their messages on their own website.

Component Definitions

The agentic fediverse is currently being designed such that messages are entities in a Entity-Component relationship. Component schemas can then be formally defined and then implemented in clients, without the need of a centralized authority releasing formal spec bumps. In theory anyone could propose a new schema.

Here's some initial ideas for components I currently plan on proposing and perhaps even implementing:

  • Community (placeholder name): Marks that replies to this message should be displayed like a collection of threads, reddit-style.
  • Delete: Marks that this message is a deletion request to the message its a reply to.
    • Can be used to delete specific components in the parent message.
  • Edit: Marks that this message is an edit request to the message its a reply to.
    • Can be used to edit specific components in the parent message.
  • Accept: Marks that any requests in the message this message is a reply to were accepted.
    • Takes an optional schema property to identify which specific request component of the parent message was accepted.
  • Reaction: Marks that this message is a reaction to the message its a reply to.
  • Ascii: Describes a text component to be rendered.
  • Unicode: Describes a text component to be rendered.
  • Image: Describes an image component to be rendered. (Or perhaps specific file formats should have their own schemas)
  • Audio: Describes an audio component to be rendered. (Or perhaps specific file formats should have their own schemas)
  • Video: Describes a video component to be rendered. (Or perhaps specific file formats should have their own schemas)
  • Topics: Describes a list of topics/tags this message is relevant to, for use in client searching and filtering.
  • Editors: Describes a list of identities who have the power to edit this message, or accept edit requests to this message.
  • Deleters: Describes a list of identities who have the power to delete this message, or accept deletion requests to this message.
  • No Discovery: Marks that this message should not be included in any global feeds or search results. Servers should only send it to servers and clients that subscribe to messages like this one.
  • Timestamp Requested: Marks that this message would like to receive a response from a trusted server (optionally defined in the component data) once it is delivered. May also include a schema ID that represents what the timestamp represents. Defaults to referring to the published date.
  • Calendar Event: Describes a calendar event.
  • RSVP: Marks that you [are, might be, or aren't] participating in whatever a linked entity is describing.

Chatting

The agentic fediverse could theoretically also implement chat rooms, bringing advantages (like divorcing identity from servers) that current decentralized chat protocols like matrix don't offer.

Here are some of the components that could be used to represent a chat room:

  • Chat room: Marks that replies to this message should be shown as messages in a chat room.
  • Bridge: Marks that this identity is a bridge for an account on another service. Implies that the verification of authorship may not be preserved.

Games

The agentic fediverse could support sharing games using a Game component that includes a url or raw html required to play a game. In theory they could even support "cloud saves" by signing a message of their save data that only they can decrypt and sending it as a reply to the game message. Clients could handle displaying the game alongside the usual filtering and sorting features.

I'd also be excited in seeing a sort of MMO style game on the agentic fediverse. So you see other players and there's a shared game state, calculated on the client based on the actions recorded by the various different players. And since the rules would have to be defined by the components, people could create their own copies of the world (e.g. to play with a friend group or solo), or even make their own mods of the game. I'd like to look into that. I'll perhaps rethink Chromatic Lattice to work on such a framework, although it may be too complicated for this idea.

Having the game state be calculatable by the client like that would also allow trophies and achievements to work verifiably. People could probably still write software to copy someone else's events at the right times and effectively replicate their save, but I think that won't happen commonly enough to matter.

Permissions

Instead of having various different licenses like CC0, MIT, etc., just make each permission discrete. For example, you can have a DoNotTrainOn component that marks that using an entity for training AI models is not allowed.

This is different from the willow permissions system which determines who can read or write to specific entities/paths. This is for telling someone who has read access to your post what they're allowed to use it for.

There should be a component that makes permissions explicit rather than implicit. E.g. assume you don't have the right to do anything unless explicitly stated.

Local identity and contact management

If I have multiple apps that use the agentic fediverse (e.g. one for reddit like content, one for Twitter, discord, Google drive, etc.), I'd like to easily have them all use the same identity(s), as well as a shared contact list (so I know the person I saw do something on one app is the same as the person that did something on another app).

To that end, there should be an app/program that manages your identities and contacts on that device. It sets up your initial identity, any cloud backups, etc., and the other apps talk to it as needed. That could be sending it individual messages to sign or asking for a key that can be used to do limited functionality.

Contacts could be signed such that they're only readable by us, and then sent over the network so I can have multiple devices that keep their contact list synced between them

An identity management app could also work as a link handler for the leaf protocol. It could take a schema ID as another path component, which then describes the purpose of the URI and the expected remaining data in the URI. The identity management app can then pass the message along to any app that has specified it knows how to handle that schema.

Sustainability

Servers are expensive, especially as they get popular. Most current fediverse instances are free and funded by donations. Things like ads or paying for an account are difficult to do due to the nature of federation. This is a pretty major problem because if a server becomes too expensive to host, it will shut down, along with all the accounts associated with it. Fedi v2 makes individual servers going down not be an issue anymore, since identities aren't attached to them. However, it's an issue if all the instances go down, and if there's no way to pay for them still, why would any instance stay up?

Since instance nodes do not have to do filtering, sorting, or really any other processing, but rather just serving the events and sending out notifications to clients, the cost will be cheaper than the current fediverse. It's really just a file server, which is cheap. For example, idrive charges $40 per tb per year, which is enough for a LOT of content. So I expect some instance nodes to have fairly generous free tiers that will suffice for a lot of users. Idrive also doesn't have egress charges, so the cost only scales with how much content is being published, not downloaded.

For power users, instance nodes could accept payments to store data above the free quota. This would likely most often happen for people wishing to upload high resolution images or videos. A user could also switch nodes after filling a quota on one node - you don't have to delete your content on the old instance. You could also do this to backup your content on multiple nodes (although you should also keep a local copy of all your content).

I assume this aspect of Fedi v2 will be the most controversial - people really like free services, and are expecting it. Knowing they might eventually need to pay to post more will perhaps require a cultural shift. I think it's worth it to not have ads or tracking, and in general we should be supporting sustainable services.

What about Incremental Social?

I think Incremental Social can operate similarly to weird.one, hosting an iroh node and storing events for the agentic fediverse for users of the site. We'll generate and manage a keypair for the user, with the possibility of the user migrating their identity.

I suspect the way the identity management app will work to support sites like weird.one and incremental.social is by passing the request for a delegate key to incremental.social, which will then show the consent screen before passing the key back to the app which sends it to the actual fediverse app.

+ \ No newline at end of file diff --git a/garden/fediverse/index.html b/garden/fediverse/index.html index 38fa02a38..301e180f6 100644 --- a/garden/fediverse/index.html +++ b/garden/fediverse/index.html @@ -6,14 +6,14 @@ Fediverse | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Fediverse

22 words, ~0 minute read. Planted +

Skip to content

Fediverse

22 words, ~0 minute read. Planted . Last tended to -.


Referenced by:ATProtoDecentralized Social MediaDecentralizedFedi v2Incremental SocialMbinNostrSocial MediaThe Small WebViralityWeird

A collection of Social Media websites that can all talk to each other by virtue of a shared protocol.

Implementations:

- +.


Referenced by:ATProtoDecentralized Social MediaDecentralizedFedi v2Incremental SocialMbinNostrSocial MediaThe Small WebViralityWeird

A collection of Social Media websites that can all talk to each other by virtue of a shared protocol.

Implementations:

+ \ No newline at end of file diff --git a/garden/filter-bubbles/index.html b/garden/filter-bubbles/index.html index de5137cc9..11ee9e78d 100644 --- a/garden/filter-bubbles/index.html +++ b/garden/filter-bubbles/index.html @@ -6,14 +6,14 @@ Filter Bubbles | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Filter Bubbles

2668 words, ~15 minute read. Planted +

Skip to content

Filter Bubbles

2668 words, ~15 minute read. Planted . Last tended to -.


Referenced by:Digital LocalityObjectivity

Filter bubbles refer to how users may be intellectually isolated as a result of Social Media with algorithmic feeds, coupled with things like personalized search engine results and other services catering to someone's existing preferences and world views.

Are you in a filter bubble?

Absolutely, and without a doubt. Filter bubbles fractal inside each other, and most of them are entirely innocuous - they're not the scary boogeyman they've been portrayed as. If your search results are primarily English - you may be in a filter bubble. If the news you watch covers domestic issues within your country more than domestic issues in other countries - you may be in a filter bubble. If the local news you watch covers the weather in your local area but not in areas halfway across the globe - you may be in a filter bubble. These are not significantly contributing to the "intellectual isolation" filter bubbles are said to create, and no one is arguing we must be equally aware of the local weather across the world.

So yes, you're in a filter bubble - likely many, even. But that's not the right question to be asking; We must delve deeper into filter bubbles' causes and manifestations to determine what their negative aspects are and ultimately how to fix them.

Filter bubbles in search engines

The author of The Filter Bubble describes what is supposed to be a chilling story of a search for BP giving results on investment opportunities to one person, and news about the oil spill disaster to another. They posit this is indicative of a problem, but I question that the personalized search results did anything wrong here. Searching BP just by itself is a "neutral" search, and so I think its fine for it to have shown results based on what its learned that user usually looks companies up for. The implication is that the former is an individual who regularly searches companies to see their current investment opportunities, and got what they wanted. If this person were to suddenly want to, say, write a report on BP's history or ecological impact, they'd naturally search for something more specific than just "BP", and certainly find the results they're looking for. And of course, there's layers to this - Google is also figuring out what search results the average person usually wants when searching a given term, and ranking those higher. So the more people search for BP to get info on the disaster, the more prominent that disaster will be.

The problems stem from the various biases we all bring with us when researching anything, whether we're in a filter bubble or not. In this regard, filter bubbles are just automated applications of our own biases. For example, if you're researching the impact of the BP ecological disaster, your pre-conceived notions over its impact - and perhaps your personal financial interests - will dictate which sources you read at all, or ultimately decide to reference or ignore when discussing the issue with others. And to be clear, all sources will have a bias. There is no such thing as Objectivity, and even seemingly "neutral" outlets are implicitly defending the status quo of society.

I think most of you may relate to this, because we're all guilty of it, myself included. I've certainly shared news articles based on the headline, and perhaps even spend a bit too much time writing and not enough reading. Research papers in particular are incredibly dry and most people will only read articles about the paper, which may not be accurate, or perhaps only read the abstract, which may not be thorough. I'm keenly aware when citing a source that its unlikely someone will actually follow that link, to the point where it almost feels futile. Perhaps even now you're only skimming this page? Taken together, it seems an article existing with a given headline is more important than any arguments held within it.

Filter bubbles in social media

The more insidious issue of filter bubbles is when it applies passively, such as when you're on social media and simply don't see anything about an important topic, say the BP oil spill. But actually, part of the issue here isn't just not seeing the post, as even if someone sees posts about the event, they may be tainted with biases towards their existing world view, and the reader will just accept that interpretation at face value. After all, most users are not going to see a headline and start doing independent research to verify the claims held within the article. Hell, most won't even go as far as reading the article itself - as has been studied many times, sometimes in quite amusing widely shared but fake "prank" articles.

Even if you click a link, you may just skim the results. This is a problem because people are not reading articles to actually learn from them, but rather to confirm their pre-existing opinions on the topic. With that reassurance in hand, they'll share the articles and feel more confident they actually understand the topic.

A lot of the articles even available to share on social media are being crafted especially to be sharable using clickbait, caring more for covering topics profitably rather than ethically. AI slop has significantly compounded this issue by being able to mass produce articles that wholly lack meaningful insight, and is now a major problem for both search engines and social media platforms.

All the biases described above contribute to an especially problematic aspect of filter bubbles: the spreading of misinformation. If people are unwilling to verify provocative but ultimately wrong claims they read in a headline, then how do we fix that? There are different approaches people have suggested: algorithmic suppression by a independent organization tasked with verifying articles' legitimacy like Facebook, relying on community-driven notes like Twitter, or just trying to shift the culture to engage with social media more productively/healthily.

Are safe spaces filter bubbles?

The internet is a dangerous place, especially for members of marginalized groups. There are a lot of -phobes in the world, and the internet gives them a platform to harass far more widespread than before. It takes concerted effort to keep them out of communities, as described by Innuendo Studios' How to radicalize a normie. I think we should all be in agreement that it is entirely fine for people to want to filter out this kind of hateful content. So safe spaces are filter bubbles, but also are good and important things to have access to.

I bring this up to really drive home that filter bubbles are not intrinsically good or bad. They happen innocuously and are even beneficial for filtering out certain kinds of content. It's important any solution to the issues with filter bubbles focuses doesn't involve exposing people to, say, those who'd like to see them dead.

The line doesn't have to be at hateful content though. There's any number of content someone may want to filter out - gore, SA, or other PTSD triggers. Ultimately the line is subjective, and where the line is shouldn't be restricted or imposed. Empathy is the key here, and the same way a trans person shouldn't be encouraged to interact with transphobes, no one should be encouraged to engage in any social interactions they deem uncomfortable, even if others don't think it's uncomfortable.

Filtering politics

In the previous section I proposed that allowing people to decide what they want to see should is important. Most people can, I imagine, agree with that, barring one notable and often contested exception: politics. Our liberal democracy insists that universal political engagement is required for it to function properly. While I agree politics are critically important, politics should not be an exception that people "must" be subjected to regardless of their consent.

A lot of political topics are deeply personal and emotionally exhausting to engage with, particularly for those marginalized under the current power structures. For example, trans rights are an extremely important political issue, but demanding that trans people continually defend their very existence against reactionary attacks amounts to a form of re-traumatization. People not being exposed to these kinds of upsetting things is not a problem to be solved, and democracy can survive while allowing people to filter out political topics or perspectives they don't want to see. You do not need to tolerate the intolerant (as argued by Karl Popper, who coined the term "paradox of tolerance").

Admittedly, as a Leftist, I desire revolutionary change and see such transformation as necessary before this framework of consent can fully hold true. Today, the drive to filter out politics often stems from alienation or reactionary thinking—a symptom of a capitalist system designed to depoliticize and pacify the masses. That's why I object to blanket policies like "No Politics" Rules that promote political apathy.

Radicalization

"Radicalization" is a nebulous term that's been used for a variety of purposes. The ACLU, for example, warns against its usage by saying this:

The government’s “radicalization” theory has become a euphemism for religious and ideological profiling. It leads to discrimination and stigmatization, and is fundamentally un-American. Casting suspicion on American faith or belief communities is wrong and does nothing to make us safer.

Personally, I think the term has been decontextualized a bit, as I see it used today to describe people moving to the left or right. In leftist communities, sharing "what radicalized you" is commonplace and not stigmatized. I think what most accurately describes radicalization is that it's the process of people moving outside the spectrum of acceptable opinion, which in American politics goes from the Republican part to the Democratic party. All other opinions are largely seen as extremist or otherwise untenable. Noam Chomsky describes how this framing perpetuates itself like this:

The smart way to keep people passive and obedient is to strictly limit the spectrum of acceptable opinion, but allow very lively debate within that spectrum—even encourage the more critical and dissident views. That gives people the sense that there's free thinking going on, while all the time the presuppositions of the system are being reinforced by the limits put on the range of the debate. - Noam Chomsky

So, personally, I don't see radicalization as an inherent issue because the current spectrum of acceptable opinion is atrocious (and, separately, an example of a filter bubble that encapsulates most of the US). I'm biased, as by my own definition I'm a radical, but I don't think radicalization should be a reason to fight against filter bubbles. Suppressing it is ultimately a way of enforcing the status quo and enabling those at the top of the status quo to perpetuate their reign.

Of course, I do want to stop people from radicalizing towards fascism. But the solution isn't to restrict all "extremist" content so that only the acceptable opinions are allowed, because fascism is acceptable! The spectrum I've been discussing is so far right that fascist and genocidal rhetoric are normal in our presidential elections and takes like "I won't vote for genocide" are met with "but ending the genocide isn't on the table". Combatting extremism explicitly means supporting our rightwards trend towards fascism.

Jubilee exemplifies the issues I'm discussing here with shows like "middle ground". Besides their clear bias in picking media trained individuals for the right but not the left, they also place the "middle ground" as being between the far right position and a moderate/central position. Funnily enough, it's a great example of why middle grounds as a concept are not intrinsically better than the extremes, as often claimed (again, in defense of the status quo). Drawing a middle point is arbitrary and tied to whatever the currently established spectrum of acceptable opinion happens to be. I recommend this podcast episode that explores the issues with Jubilee and the "free market of ideas". Naturally, they also uphold the principle that marginalized groups should be expected to relive their traumatic experiences with those who wish them harm, under the justification that democracy falls without that.

Echo Chambers vs Filter Bubbles

I've been mostly referring to filter bubbles all this time, but it's time to make an important distinction that will really tie this whole thing together. Filter bubbles are simply having preferences towards the kind of content you see being reflected by algorithms. They can be emergent or intentional, are often innocuous and even helpful, and sometimes may be bad. They have no intrinsic moral value.

Echo Chambers is the term for when filter bubbles turn bad. This is the term for when those inside a filter bubble turn against those outside it. When the only portrayal of those outside the bubble are hateful caricatures from those within it. This is truly where the hateful content and misinformation comes from. Echo Chambers are the problem to solve. But since they're composed of two parts - filter bubbles and hateful content and misinformation - we have a choice for approaching the problem.

Traditionally, people argue the solution to echo chambers is removing the filter bubbles. That if people are simply exposed to more ideas, the echo chamber goes away. As discussed earlier, this cannot be accepted when some of those ideas actively wish harm upon you.

The other approach is just solving the issues with misinformation and hateful content directly. They cannot be tolerated, and should be entirely suppressed. Free speech should not protect people actively doing harm upon others.

Moderating away hate and misinformation

So if the issue isn't the filter bubbles but rather hateful content and misinformation... what do we do to combat it?

On an individual level, we can try to improve our media literacy and spread accurate information with positive values like DEI and class consciousness. Every person counts, although the system is working against us currently.

On a systemic level, a new social media can be designed so they are more protected from misinformation spreading. For example, by allowing users to publicly "vouch" for other users for writing and sharing accurate posts, forming a web of trust/reputation. Also designing the network so those who are popular are not prioritized in algorithmic feeds, essentially centralizing influence into the hands of the few. I explore this topic and other aspects to a radical new social media network in Fedi v2 and Digital Locality.

Taking a step back, several of these issues described - clickbait and spam, specifically - only exist due to financial incentives brought on by our capitalist system. Additionally, Capitalism is the reason for people not having the time, energy, or motivation to more healthily approach social media and combat misinformation. Therefore, we need a Leftist shift to fix these problems and bring us to a more media literate society free of influencers and advertisers. It's the only long term solution.

Message gardening

This is largely theoretical, but something I've been thinking of a lot about are Digital Gardens, and I think the philosophy of them could lead to a different kind of solution to tackling hate and misinformation. Right now a lot of news and discourse about said news is essentially frozen in time. Corrections to stories never get as much attention as the original incorrect story. We have the same discussions over and over again. I thinking we could improve this situation by explicitly framing social media as a tool for building a network of knowledge, like a wiki (or rather, a communal digital garden).

This is something that would need to be explored more before it could be implemented, but I'm sort of envisioning something like twitter's community notes system alongside something like Commune where informal discussions are part of a process of continuously updating a formal document about the topic/event, with new developments, perspectives, and context. I think structuring social media this way, and updating people of important changes to these formal documents people have read or participated in, could lead to a more well informed populace.

Further Reading

Everything discussed in this article falls under the field of sociology, so you may be interested in looking more into that study. I recommend a few of the games by Nicky Case, which share a common thread of exploring sociological concepts:

- +.


Referenced by:Digital LocalityObjectivity

Filter bubbles refer to how users may be intellectually isolated as a result of Social Media with algorithmic feeds, coupled with things like personalized search engine results and other services catering to someone's existing preferences and world views.

Are you in a filter bubble?

Absolutely, and without a doubt. Filter bubbles fractal inside each other, and most of them are entirely innocuous - they're not the scary boogeyman they've been portrayed as. If your search results are primarily English - you may be in a filter bubble. If the news you watch covers domestic issues within your country more than domestic issues in other countries - you may be in a filter bubble. If the local news you watch covers the weather in your local area but not in areas halfway across the globe - you may be in a filter bubble. These are not significantly contributing to the "intellectual isolation" filter bubbles are said to create, and no one is arguing we must be equally aware of the local weather across the world.

So yes, you're in a filter bubble - likely many, even. But that's not the right question to be asking; We must delve deeper into filter bubbles' causes and manifestations to determine what their negative aspects are and ultimately how to fix them.

Filter bubbles in search engines

The author of The Filter Bubble describes what is supposed to be a chilling story of a search for BP giving results on investment opportunities to one person, and news about the oil spill disaster to another. They posit this is indicative of a problem, but I question that the personalized search results did anything wrong here. Searching BP just by itself is a "neutral" search, and so I think its fine for it to have shown results based on what its learned that user usually looks companies up for. The implication is that the former is an individual who regularly searches companies to see their current investment opportunities, and got what they wanted. If this person were to suddenly want to, say, write a report on BP's history or ecological impact, they'd naturally search for something more specific than just "BP", and certainly find the results they're looking for. And of course, there's layers to this - Google is also figuring out what search results the average person usually wants when searching a given term, and ranking those higher. So the more people search for BP to get info on the disaster, the more prominent that disaster will be.

The problems stem from the various biases we all bring with us when researching anything, whether we're in a filter bubble or not. In this regard, filter bubbles are just automated applications of our own biases. For example, if you're researching the impact of the BP ecological disaster, your pre-conceived notions over its impact - and perhaps your personal financial interests - will dictate which sources you read at all, or ultimately decide to reference or ignore when discussing the issue with others. And to be clear, all sources will have a bias. There is no such thing as Objectivity, and even seemingly "neutral" outlets are implicitly defending the status quo of society.

I think most of you may relate to this, because we're all guilty of it, myself included. I've certainly shared news articles based on the headline, and perhaps even spend a bit too much time writing and not enough reading. Research papers in particular are incredibly dry and most people will only read articles about the paper, which may not be accurate, or perhaps only read the abstract, which may not be thorough. I'm keenly aware when citing a source that its unlikely someone will actually follow that link, to the point where it almost feels futile. Perhaps even now you're only skimming this page? Taken together, it seems an article existing with a given headline is more important than any arguments held within it.

Filter bubbles in social media

The more insidious issue of filter bubbles is when it applies passively, such as when you're on social media and simply don't see anything about an important topic, say the BP oil spill. But actually, part of the issue here isn't just not seeing the post, as even if someone sees posts about the event, they may be tainted with biases towards their existing world view, and the reader will just accept that interpretation at face value. After all, most users are not going to see a headline and start doing independent research to verify the claims held within the article. Hell, most won't even go as far as reading the article itself - as has been studied many times, sometimes in quite amusing widely shared but fake "prank" articles.

Even if you click a link, you may just skim the results. This is a problem because people are not reading articles to actually learn from them, but rather to confirm their pre-existing opinions on the topic. With that reassurance in hand, they'll share the articles and feel more confident they actually understand the topic.

A lot of the articles even available to share on social media are being crafted especially to be sharable using clickbait, caring more for covering topics profitably rather than ethically. AI slop has significantly compounded this issue by being able to mass produce articles that wholly lack meaningful insight, and is now a major problem for both search engines and social media platforms.

All the biases described above contribute to an especially problematic aspect of filter bubbles: the spreading of misinformation. If people are unwilling to verify provocative but ultimately wrong claims they read in a headline, then how do we fix that? There are different approaches people have suggested: algorithmic suppression by a independent organization tasked with verifying articles' legitimacy like Facebook, relying on community-driven notes like Twitter, or just trying to shift the culture to engage with social media more productively/healthily.

Are safe spaces filter bubbles?

The internet is a dangerous place, especially for members of marginalized groups. There are a lot of -phobes in the world, and the internet gives them a platform to harass far more widespread than before. It takes concerted effort to keep them out of communities, as described by Innuendo Studios' How to radicalize a normie. I think we should all be in agreement that it is entirely fine for people to want to filter out this kind of hateful content. So safe spaces are filter bubbles, but also are good and important things to have access to.

I bring this up to really drive home that filter bubbles are not intrinsically good or bad. They happen innocuously and are even beneficial for filtering out certain kinds of content. It's important any solution to the issues with filter bubbles focuses doesn't involve exposing people to, say, those who'd like to see them dead.

The line doesn't have to be at hateful content though. There's any number of content someone may want to filter out - gore, SA, or other PTSD triggers. Ultimately the line is subjective, and where the line is shouldn't be restricted or imposed. Empathy is the key here, and the same way a trans person shouldn't be encouraged to interact with transphobes, no one should be encouraged to engage in any social interactions they deem uncomfortable, even if others don't think it's uncomfortable.

Filtering politics

In the previous section I proposed that allowing people to decide what they want to see should is important. Most people can, I imagine, agree with that, barring one notable and often contested exception: politics. Our liberal democracy insists that universal political engagement is required for it to function properly. While I agree politics are critically important, politics should not be an exception that people "must" be subjected to regardless of their consent.

A lot of political topics are deeply personal and emotionally exhausting to engage with, particularly for those marginalized under the current power structures. For example, trans rights are an extremely important political issue, but demanding that trans people continually defend their very existence against reactionary attacks amounts to a form of re-traumatization. People not being exposed to these kinds of upsetting things is not a problem to be solved, and democracy can survive while allowing people to filter out political topics or perspectives they don't want to see. You do not need to tolerate the intolerant (as argued by Karl Popper, who coined the term "paradox of tolerance").

Admittedly, as a Leftist, I desire revolutionary change and see such transformation as necessary before this framework of consent can fully hold true. Today, the drive to filter out politics often stems from alienation or reactionary thinking—a symptom of a capitalist system designed to depoliticize and pacify the masses. That's why I object to blanket policies like "No Politics" Rules that promote political apathy.

Radicalization

"Radicalization" is a nebulous term that's been used for a variety of purposes. The ACLU, for example, warns against its usage by saying this:

The government’s “radicalization” theory has become a euphemism for religious and ideological profiling. It leads to discrimination and stigmatization, and is fundamentally un-American. Casting suspicion on American faith or belief communities is wrong and does nothing to make us safer.

Personally, I think the term has been decontextualized a bit, as I see it used today to describe people moving to the left or right. In leftist communities, sharing "what radicalized you" is commonplace and not stigmatized. I think what most accurately describes radicalization is that it's the process of people moving outside the spectrum of acceptable opinion, which in American politics goes from the Republican part to the Democratic party. All other opinions are largely seen as extremist or otherwise untenable. Noam Chomsky describes how this framing perpetuates itself like this:

The smart way to keep people passive and obedient is to strictly limit the spectrum of acceptable opinion, but allow very lively debate within that spectrum—even encourage the more critical and dissident views. That gives people the sense that there's free thinking going on, while all the time the presuppositions of the system are being reinforced by the limits put on the range of the debate. - Noam Chomsky

So, personally, I don't see radicalization as an inherent issue because the current spectrum of acceptable opinion is atrocious (and, separately, an example of a filter bubble that encapsulates most of the US). I'm biased, as by my own definition I'm a radical, but I don't think radicalization should be a reason to fight against filter bubbles. Suppressing it is ultimately a way of enforcing the status quo and enabling those at the top of the status quo to perpetuate their reign.

Of course, I do want to stop people from radicalizing towards fascism. But the solution isn't to restrict all "extremist" content so that only the acceptable opinions are allowed, because fascism is acceptable! The spectrum I've been discussing is so far right that fascist and genocidal rhetoric are normal in our presidential elections and takes like "I won't vote for genocide" are met with "but ending the genocide isn't on the table". Combatting extremism explicitly means supporting our rightwards trend towards fascism.

Jubilee exemplifies the issues I'm discussing here with shows like "middle ground". Besides their clear bias in picking media trained individuals for the right but not the left, they also place the "middle ground" as being between the far right position and a moderate/central position. Funnily enough, it's a great example of why middle grounds as a concept are not intrinsically better than the extremes, as often claimed (again, in defense of the status quo). Drawing a middle point is arbitrary and tied to whatever the currently established spectrum of acceptable opinion happens to be. I recommend this podcast episode that explores the issues with Jubilee and the "free market of ideas". Naturally, they also uphold the principle that marginalized groups should be expected to relive their traumatic experiences with those who wish them harm, under the justification that democracy falls without that.

Echo Chambers vs Filter Bubbles

I've been mostly referring to filter bubbles all this time, but it's time to make an important distinction that will really tie this whole thing together. Filter bubbles are simply having preferences towards the kind of content you see being reflected by algorithms. They can be emergent or intentional, are often innocuous and even helpful, and sometimes may be bad. They have no intrinsic moral value.

Echo Chambers is the term for when filter bubbles turn bad. This is the term for when those inside a filter bubble turn against those outside it. When the only portrayal of those outside the bubble are hateful caricatures from those within it. This is truly where the hateful content and misinformation comes from. Echo Chambers are the problem to solve. But since they're composed of two parts - filter bubbles and hateful content and misinformation - we have a choice for approaching the problem.

Traditionally, people argue the solution to echo chambers is removing the filter bubbles. That if people are simply exposed to more ideas, the echo chamber goes away. As discussed earlier, this cannot be accepted when some of those ideas actively wish harm upon you.

The other approach is just solving the issues with misinformation and hateful content directly. They cannot be tolerated, and should be entirely suppressed. Free speech should not protect people actively doing harm upon others.

Moderating away hate and misinformation

So if the issue isn't the filter bubbles but rather hateful content and misinformation... what do we do to combat it?

On an individual level, we can try to improve our media literacy and spread accurate information with positive values like DEI and class consciousness. Every person counts, although the system is working against us currently.

On a systemic level, a new social media can be designed so they are more protected from misinformation spreading. For example, by allowing users to publicly "vouch" for other users for writing and sharing accurate posts, forming a web of trust/reputation. Also designing the network so those who are popular are not prioritized in algorithmic feeds, essentially centralizing influence into the hands of the few. I explore this topic and other aspects to a radical new social media network in Fedi v2 and Digital Locality.

Taking a step back, several of these issues described - clickbait and spam, specifically - only exist due to financial incentives brought on by our capitalist system. Additionally, Capitalism is the reason for people not having the time, energy, or motivation to more healthily approach social media and combat misinformation. Therefore, we need a Leftist shift to fix these problems and bring us to a more media literate society free of influencers and advertisers. It's the only long term solution.

Message gardening

This is largely theoretical, but something I've been thinking of a lot about are Digital Gardens, and I think the philosophy of them could lead to a different kind of solution to tackling hate and misinformation. Right now a lot of news and discourse about said news is essentially frozen in time. Corrections to stories never get as much attention as the original incorrect story. We have the same discussions over and over again. I thinking we could improve this situation by explicitly framing social media as a tool for building a network of knowledge, like a wiki (or rather, a communal digital garden).

This is something that would need to be explored more before it could be implemented, but I'm sort of envisioning something like twitter's community notes system alongside something like Commune where informal discussions are part of a process of continuously updating a formal document about the topic/event, with new developments, perspectives, and context. I think structuring social media this way, and updating people of important changes to these formal documents people have read or participated in, could lead to a more well informed populace.

Further Reading

Everything discussed in this article falls under the field of sociology, so you may be interested in looking more into that study. I recommend a few of the games by Nicky Case, which share a common thread of exploring sociological concepts:

+ \ No newline at end of file diff --git a/garden/forgejo/index.html b/garden/forgejo/index.html index 2572e1912..c705b443d 100644 --- a/garden/forgejo/index.html +++ b/garden/forgejo/index.html @@ -6,14 +6,14 @@ Forgejo | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Forgejo

5 words, ~0 minute read. Planted +

Skip to content

Forgejo

5 words, ~0 minute read. Planted . Last tended to -.


Referenced by:Incremental Social

Forgejo is an Open Source code repository hosting software

- +.


Referenced by:Incremental Social

Forgejo is an Open Source code repository hosting software

+ \ No newline at end of file diff --git a/garden/freeform-vs-chronological-dichotomy/index.html b/garden/freeform-vs-chronological-dichotomy/index.html index 856e107c2..e50e846e9 100644 --- a/garden/freeform-vs-chronological-dichotomy/index.html +++ b/garden/freeform-vs-chronological-dichotomy/index.html @@ -6,14 +6,14 @@ Freeform vs Chronological Dichotomy | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Freeform vs Chronological Dichotomy

10 words, ~0 minute read. Planted +

Skip to content

Freeform vs Chronological Dichotomy

10 words, ~0 minute read. Planted . Last tended to -.


Referenced by:ChronologicalFreeform

Describes a dichotomy between displaying information in a Freeform vs Chronological manner

- +.


Referenced by:ChronologicalFreeform

Describes a dichotomy between displaying information in a Freeform vs Chronological manner

+ \ No newline at end of file diff --git a/garden/freeform/index.html b/garden/freeform/index.html index 71c13cf79..5f6d91225 100644 --- a/garden/freeform/index.html +++ b/garden/freeform/index.html @@ -6,14 +6,14 @@ Freeform | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Freeform

46 words, ~0 minute read. Planted +

Skip to content

Freeform

46 words, ~0 minute read. Planted . Last tended to -.


Referenced by:CommuneDigital GardensFreeform vs Chronological DichotomyGarden-RSS

A collection of information that is not tied to when it was created or edited

Part of the Freeform vs Chronological Dichotomy

Anything wiki-style is considered freeform

  • A collection of living documents

Garden-RSS, a theoretical alternative to RSS that's better for freeform content

- +.


Referenced by:CommuneDigital GardensFreeform vs Chronological DichotomyGarden-RSS

A collection of information that is not tied to when it was created or edited

Part of the Freeform vs Chronological Dichotomy

Anything wiki-style is considered freeform

  • A collection of living documents

Garden-RSS, a theoretical alternative to RSS that's better for freeform content

+ \ No newline at end of file diff --git a/garden/game-dev-tree/index.html b/garden/game-dev-tree/index.html index f06e1dc5f..5b8131fbb 100644 --- a/garden/game-dev-tree/index.html +++ b/garden/game-dev-tree/index.html @@ -6,14 +6,14 @@ Game Dev Tree | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Game Dev Tree

34 words, ~0 minute read. Planted +

Skip to content

Game Dev Tree

34 words, ~0 minute read. Planted . Last tended to -.


Tags:My Projects

Play it here!

My first (good) incremental game! (My actual first was Shape Tycoon - I don't recommend it!)

It's Open Source!

The TV Tropes page on this game mentions some of the cool things about this game

- +.


Tags:My Projects

Play it here!

My first (good) incremental game! (My actual first was Shape Tycoon - I don't recommend it!)

It's Open Source!

The TV Tropes page on this game mentions some of the cool things about this game

+ \ No newline at end of file diff --git a/garden/garden-rss/index.html b/garden/garden-rss/index.html index 893349423..10ed6f2d5 100644 --- a/garden/garden-rss/index.html +++ b/garden/garden-rss/index.html @@ -6,14 +6,14 @@ Garden-RSS | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Garden-RSS

59 words, ~0 minute read. Planted +

Skip to content

Garden-RSS

59 words, ~0 minute read. Planted . Last tended to -.


Referenced by:FreeformOrchardThe Small WebThis Knowledge Hub

A theoretical alternative to RSS that's better for Freeform websites (and Digital Gardens specifically )

Why is it useful?

How should it work?

  • Could display changes similar to git diffs

Existing Work

- +.


Referenced by:FreeformOrchardThe Small WebThis Knowledge Hub

A theoretical alternative to RSS that's better for Freeform websites (and Digital Gardens specifically )

Why is it useful?

How should it work?

  • Could display changes similar to git diffs

Existing Work

+ \ No newline at end of file diff --git a/garden/gender-performativity/index.html b/garden/gender-performativity/index.html index df7d0e731..156d52da2 100644 --- a/garden/gender-performativity/index.html +++ b/garden/gender-performativity/index.html @@ -6,14 +6,14 @@ Gender Performativity | The Paper Pilot - + - + - - - + + + @@ -53,9 +53,9 @@ -
Skip to content

Gender Performativity

2 words, ~0 minute read. Planted -.


Referenced by:ObjectivityPersonality

A Gender theory by Judith Butler, as described in Gender Trouble. Butler argues that we observe gender norms performed by others and reproduce them. In this way, gender is a force that acts upon us. Philosophy Tube describes this theory in more detail in I read the most misunderstood philosopher in the world

- +
Skip to content

Gender Performativity

2 words, ~0 minute read. Planted +.


Referenced by:ObjectivityPersonality

A Gender theory by Judith Butler, as described in Gender Trouble. Butler argues that we observe gender norms performed by others and reproduce them. In this way, gender is a force that acts upon us. Philosophy Tube describes this theory in more detail in I read the most misunderstood philosopher in the world

+ \ No newline at end of file diff --git a/garden/gender/index.html b/garden/gender/index.html index 2fafff4b7..3acbc05da 100644 --- a/garden/gender/index.html +++ b/garden/gender/index.html @@ -6,14 +6,14 @@ Gender | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Gender

741 words, ~4 minute read. Planted +

Skip to content

Gender

741 words, ~4 minute read. Planted . Last tended to -.


Referenced by:Gender PerformativitySocial ConstructsTrans athletes in sports

Gender is a tricky subject, and there are many conflicting frameworks that have been proposed for defining gender and measuring its impact, and other such aspects of it. Judith Butler, for example, controversially describes gender as a performance); We observe how people act, what they seem to enjoy, and what roles they fill in society based on their gender, and then we (often subconsciously) perform similarly, perpetuating the cycle. That makes gender a Social Construct.

Gender is a very sensitive topic, especially as people's identities are constantly under attack within the west. I'd like to make it explicitly clear I support any and all gender identities, and re-affirm that just because something is a construct does not mean its bad or useless. It just means society has decided to give it meaning, and I think gender will be very meaningful to people for a very very long time. These frameworks used for analyzing it and determining its utility are some nice philosophical exercises, but above all it should be clear any political goal should be to eliminate discrimination against marginalized peoples.

There are some people who believe gender is an exclusively unuseful and negative social construct and should be entirely abolished, and see this act as a requirement for liberating queer people and women. You'll see plenty of people push back on this idea, saying they like their genders, though, and sometimes even trying to co-opt "gender abolitionism" as referring to only abolishing gender roles rather than gender itself as a construct. It's seen as a stance that essentially invalidates the motivation behind so many people going through great efforts to transition from one gender to another. An even more pessimistic stance on gender abolition sees it as a return to biological sex, even further erasing the plights of trans people. However, I think as society progresses towards post-scarcity, a lot of constructs will over time see a natural end as they become less useful, and I do think we'll eventually see a post-gender society where everyone is just "themselves", and the realm of self expression is massively expanded, but no longer sees a need for gender as a construct.

Alright, with that established it's time for another controversial take: Biological sex is also a social construct. Sex is a term used to refer to a collection of underlying natural properties from which sex determining genes one has, which sex chromosomes are present, how much of each sex hormone gets produced, which genitals one has, which hormones get processed, what happens during puberty, and so on. Besides the fact there's plenty of people who don't have every single of the above properties cleanly fit into the same bucket, the fact we choose to imbue those properties with meaning makes them a construct as well, and in fact we imbued them with so much meaning we built our entire society around it. Sure, we created gender as a way of abstracting the roles in the society from the natural properties, but ultimately they're both just as arbitrary distinctions we collectively chose to make. And yet, positioning gender as the social construct and biological sex as the "objective" underlying property, you open the door to essentially continue discriminating against a significant amount of the population, using "truth" and "science" to justify their position.

To be clear, I'm not saying biology doesn't matter (and neither does anyone else who argues sex is also a social construct). Obviously someone with a uterus is going to have different medical risks and opportunities than someone without. But using the presence of that uterus to socially and culturally discriminate against someone is not okay. In fact, society placing importance on the number of years spent at a job is a form of discriminating against people who choose to take time off work to be a parent, even if their actual ability to perform that job is not impacted at all. This impacts both career trajectory as well as making it more difficult to even get some jobs in the first place. I recommend Biological sex is a social construct for further exploration into this concept.

Identity, Gender, and VRChat explores how VRChat has enabled people to explore their gender expression and other parts of their identity in a low risk and very accepting environment. I haven't used VRChat myself, but that sounds like an amazing resource for people to be able to use, and honestly makes me hope socializing in VR becomes an increasingly normalized and accessible activity.

- +.


Referenced by:Gender PerformativitySocial ConstructsTrans athletes in sports

Gender is a tricky subject, and there are many conflicting frameworks that have been proposed for defining gender and measuring its impact, and other such aspects of it. Judith Butler, for example, controversially describes gender as a performance); We observe how people act, what they seem to enjoy, and what roles they fill in society based on their gender, and then we (often subconsciously) perform similarly, perpetuating the cycle. That makes gender a Social Construct.

Gender is a very sensitive topic, especially as people's identities are constantly under attack within the west. I'd like to make it explicitly clear I support any and all gender identities, and re-affirm that just because something is a construct does not mean its bad or useless. It just means society has decided to give it meaning, and I think gender will be very meaningful to people for a very very long time. These frameworks used for analyzing it and determining its utility are some nice philosophical exercises, but above all it should be clear any political goal should be to eliminate discrimination against marginalized peoples.

There are some people who believe gender is an exclusively unuseful and negative social construct and should be entirely abolished, and see this act as a requirement for liberating queer people and women. You'll see plenty of people push back on this idea, saying they like their genders, though, and sometimes even trying to co-opt "gender abolitionism" as referring to only abolishing gender roles rather than gender itself as a construct. It's seen as a stance that essentially invalidates the motivation behind so many people going through great efforts to transition from one gender to another. An even more pessimistic stance on gender abolition sees it as a return to biological sex, even further erasing the plights of trans people. However, I think as society progresses towards post-scarcity, a lot of constructs will over time see a natural end as they become less useful, and I do think we'll eventually see a post-gender society where everyone is just "themselves", and the realm of self expression is massively expanded, but no longer sees a need for gender as a construct.

Alright, with that established it's time for another controversial take: Biological sex is also a social construct. Sex is a term used to refer to a collection of underlying natural properties from which sex determining genes one has, which sex chromosomes are present, how much of each sex hormone gets produced, which genitals one has, which hormones get processed, what happens during puberty, and so on. Besides the fact there's plenty of people who don't have every single of the above properties cleanly fit into the same bucket, the fact we choose to imbue those properties with meaning makes them a construct as well, and in fact we imbued them with so much meaning we built our entire society around it. Sure, we created gender as a way of abstracting the roles in the society from the natural properties, but ultimately they're both just as arbitrary distinctions we collectively chose to make. And yet, positioning gender as the social construct and biological sex as the "objective" underlying property, you open the door to essentially continue discriminating against a significant amount of the population, using "truth" and "science" to justify their position.

To be clear, I'm not saying biology doesn't matter (and neither does anyone else who argues sex is also a social construct). Obviously someone with a uterus is going to have different medical risks and opportunities than someone without. But using the presence of that uterus to socially and culturally discriminate against someone is not okay. In fact, society placing importance on the number of years spent at a job is a form of discriminating against people who choose to take time off work to be a parent, even if their actual ability to perform that job is not impacted at all. This impacts both career trajectory as well as making it more difficult to even get some jobs in the first place. I recommend Biological sex is a social construct for further exploration into this concept.

Identity, Gender, and VRChat explores how VRChat has enabled people to explore their gender expression and other parts of their identity in a low risk and very accepting environment. I haven't used VRChat myself, but that sounds like an amazing resource for people to be able to use, and honestly makes me hope socializing in VR becomes an increasingly normalized and accessible activity.

+ \ No newline at end of file diff --git a/garden/gerrymandering/index.html b/garden/gerrymandering/index.html index 794d06b82..ddf05d90c 100644 --- a/garden/gerrymandering/index.html +++ b/garden/gerrymandering/index.html @@ -6,14 +6,14 @@ Gerrymandering | The Paper Pilot - + - + - - - + + + @@ -53,9 +53,9 @@ -
Skip to content

Gerrymandering

926 words, ~5 minute read. Planted -.


Gerrymandering, or the deliberate outlining of voting districts in order to consolidate or spread out voters who you expect to vote similarly to each other, is typically portrayed as an unambiguously unfair thing to do. And I (typically) agree! But there are some interesting caveats that illustrate how illusory our concept of fairness really is, that demonstrate it is in fact a Social Construct. For example, Louisiana's most recent redistricting (in 2024) stirred up controversy for a new district, district 6, being drawn with very weird borders, specifically to ensure it has a majority of black voters who were previously more spread out across the districts. This is classic gerrymandering that makes it so that voting bloc determines the result of that district and the one already existing majority black district, but has nominal impact on any of the other 4 districts. But this process is actually being argued to be more fair to black voters, because previous congressional maps, despite appearing more fair, were not very proportional to race by only having 1 majority black district versus 5 majority white districts. This is the racial composition of Louisiana based on census data from 2017 to 2021, and the new congressional map highlighting the 2 districts that are majority black:

Source: [Neilsberg](https://www.neilsberg.com/insights/topic/louisiana-population/)
Source: [Democracy Docket](https://www.democracydocket.com/news-alerts/new-louisiana-congressional-map-with-two-majority-black-districts-heads-to-governor/)

Having 2 districts means black voters are represented by 1/3 of the districts, which is remarkably proportional, considering they make up 32% of the population. In this way, the gerrymandering is being employed to make the district representation more proportional by race, which groups like the NAACP argue makes them more fair. I agree with their assessment and think this will make Louisiana much more fair, and that's awesome. Naturally, it is being sued for its obvious gerrymandering however, with arguments that it is making the election less fair, under the definition that gerrymandering is intrinsically unfair.

Both sides of the argument are dealing with conflicting definitions of fairness. Determining it based on how close to square each district ends up is just as arbitrary as making them proportional by race. They could have been proportional by age or party or hobby. And in any case, 6 representatives means the proportions are going to be very crude proportions in anyways - the racial composition showed no other races reached the ~1/6 of a population required to be given a single representative, so is it "fair" that they don't get any representative of their own? And is it even fair to be treating racial demographics as a monolithic voting blocs in the first place? Sure those two districts are gerrymandered to be majority black, but what if they're also all the black voters that voted a specific way, and the ones who voted another way are the ones still spread out across the majority white districts?

These are not new insights, and in fact many argue that congressional districts should just use proportional representation directly, which would allow for larger districts with multiple representatives based on votes (such as a ranked choice vote, where you keep picking the most voted person, redistribute their votes to their next pick, and continue until all representatives picked), regardless of demographics or how anyone decided to draw up lines on a map... Except even then, what if the larger districts are still gerrymandered? What if the state itself is gerrymandered? Louisiana being composed of 32% black voters is "packed" considering the US as a whole only has a 12% black population. And unless we increase the number of representatives, there's likely still going to be demographics and political dispositions that lack even a single representative. But maybe some would argue below that 1 representative threshold, those demographics and political views aren't significant enough to warrant a material impact on how the area is run?

I've been mentioning race a lot here, but I think it's important to understand why that demographic specifically is considered so important to account for here. America is and has been a racist country for a long time, with many issues present in the system itself, and therefore our social constructs as well. Black people have been regularly under-represented in our government and suffered greatly for it. I've been making the case that proportionality by race is a reasonable metric for fairness, but to be honest there's quite a strong case that, due to historical oppression, black people may deserve to be over-represented in order to help them regain equal footing in our society. To help correct the racist parts very much still present in our laws and processes, which may be hard to do if a minority of our representatives are chosen by black people. This adds a whole new facet to our discussion on fairness that I'm only briefly touching on here, but even proportionality may not be considered "fair", due to its ambivalence to historical context.

My personal stance on what would be most fair is actually that representation is intrinsically an inaccurate abstraction of the people's political will. I think the closer we get to having individuals voting directly on the issues the better (see Direct Democracy ), and beyond that I'd ideally prefer a system where policies are workshopped and ideated upon until they can achieve a near unanimous vote before being implemented (see Consensus Democracy ). But hopefully all of this goes to show how complex fairness is, and how there is no "objectively" definition of fairness. Therefore, arguments should not center on appeals to "fairness" like its some objective or authoritative measure. You must be able to justify why your policy improves things in material. And to clarify, I do support the new congressional map that makes two majority black voting districts - I'm all for harm reduction, and that map is the least we can do in trying to make the system more fair, by most reasonable definitions of fairness.

- +
Skip to content

Gerrymandering

926 words, ~5 minute read. Planted +.


Gerrymandering, or the deliberate outlining of voting districts in order to consolidate or spread out voters who you expect to vote similarly to each other, is typically portrayed as an unambiguously unfair thing to do. And I (typically) agree! But there are some interesting caveats that illustrate how illusory our concept of fairness really is, that demonstrate it is in fact a Social Construct. For example, Louisiana's most recent redistricting (in 2024) stirred up controversy for a new district, district 6, being drawn with very weird borders, specifically to ensure it has a majority of black voters who were previously more spread out across the districts. This is classic gerrymandering that makes it so that voting bloc determines the result of that district and the one already existing majority black district, but has nominal impact on any of the other 4 districts. But this process is actually being argued to be more fair to black voters, because previous congressional maps, despite appearing more fair, were not very proportional to race by only having 1 majority black district versus 5 majority white districts. This is the racial composition of Louisiana based on census data from 2017 to 2021, and the new congressional map highlighting the 2 districts that are majority black:

Source: [Neilsberg](https://www.neilsberg.com/insights/topic/louisiana-population/)
Source: [Democracy Docket](https://www.democracydocket.com/news-alerts/new-louisiana-congressional-map-with-two-majority-black-districts-heads-to-governor/)

Having 2 districts means black voters are represented by 1/3 of the districts, which is remarkably proportional, considering they make up 32% of the population. In this way, the gerrymandering is being employed to make the district representation more proportional by race, which groups like the NAACP argue makes them more fair. I agree with their assessment and think this will make Louisiana much more fair, and that's awesome. Naturally, it is being sued for its obvious gerrymandering however, with arguments that it is making the election less fair, under the definition that gerrymandering is intrinsically unfair.

Both sides of the argument are dealing with conflicting definitions of fairness. Determining it based on how close to square each district ends up is just as arbitrary as making them proportional by race. They could have been proportional by age or party or hobby. And in any case, 6 representatives means the proportions are going to be very crude proportions in anyways - the racial composition showed no other races reached the ~1/6 of a population required to be given a single representative, so is it "fair" that they don't get any representative of their own? And is it even fair to be treating racial demographics as a monolithic voting blocs in the first place? Sure those two districts are gerrymandered to be majority black, but what if they're also all the black voters that voted a specific way, and the ones who voted another way are the ones still spread out across the majority white districts?

These are not new insights, and in fact many argue that congressional districts should just use proportional representation directly, which would allow for larger districts with multiple representatives based on votes (such as a ranked choice vote, where you keep picking the most voted person, redistribute their votes to their next pick, and continue until all representatives picked), regardless of demographics or how anyone decided to draw up lines on a map... Except even then, what if the larger districts are still gerrymandered? What if the state itself is gerrymandered? Louisiana being composed of 32% black voters is "packed" considering the US as a whole only has a 12% black population. And unless we increase the number of representatives, there's likely still going to be demographics and political dispositions that lack even a single representative. But maybe some would argue below that 1 representative threshold, those demographics and political views aren't significant enough to warrant a material impact on how the area is run?

I've been mentioning race a lot here, but I think it's important to understand why that demographic specifically is considered so important to account for here. America is and has been a racist country for a long time, with many issues present in the system itself, and therefore our social constructs as well. Black people have been regularly under-represented in our government and suffered greatly for it. I've been making the case that proportionality by race is a reasonable metric for fairness, but to be honest there's quite a strong case that, due to historical oppression, black people may deserve to be over-represented in order to help them regain equal footing in our society. To help correct the racist parts very much still present in our laws and processes, which may be hard to do if a minority of our representatives are chosen by black people. This adds a whole new facet to our discussion on fairness that I'm only briefly touching on here, but even proportionality may not be considered "fair", due to its ambivalence to historical context.

My personal stance on what would be most fair is actually that representation is intrinsically an inaccurate abstraction of the people's political will. I think the closer we get to having individuals voting directly on the issues the better (see Direct Democracy ), and beyond that I'd ideally prefer a system where policies are workshopped and ideated upon until they can achieve a near unanimous vote before being implemented (see Consensus Democracy ). But hopefully all of this goes to show how complex fairness is, and how there is no "objectively" definition of fairness. Therefore, arguments should not center on appeals to "fairness" like its some objective or authoritative measure. You must be able to justify why your policy improves things in material. And to clarify, I do support the new congressional map that makes two majority black voting districts - I'm all for harm reduction, and that map is the least we can do in trying to make the system more fair, by most reasonable definitions of fairness.

+ \ No newline at end of file diff --git a/garden/guide-to-incrementals/appeal-to-developers/index.html b/garden/guide-to-incrementals/appeal-to-developers/index.html index 2c8e9c6d2..e838ca9e9 100644 --- a/garden/guide-to-incrementals/appeal-to-developers/index.html +++ b/garden/guide-to-incrementals/appeal-to-developers/index.html @@ -6,14 +6,14 @@ Guide to Incrementals/Appeal to Developers | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Guide to Incrementals/Appeal to Developers

636 words, ~3 minute read. Planted +

Skip to content

Guide to Incrementals/Appeal to Developers

636 words, ~3 minute read. Planted . Last tended to -.


Referenced by:Incremental SocialKronos

There are a lot of developers in the incremental games community - the genre seems to draw them in, and convert a lot of players into developers. Let's explore the reasons why this genre appeals to developers.

Incrementals are Easy to Make

Compared to other genres, incrementals have quite low expectations. You don't need to make fancy art, or music, or lay things out nicely. If you can make a button and learn the few lines of code necessary to make a number go up, you can make an incremental. This low threshold makes the genre perfect for those who are actively learning to code and haven't developed any gamedev-related skills yet.

Additionally, unlike other genres incrementals are uniquely easy to implement in a normal web page - no need to worry about rendering sprites, moving them around, implementing physics, etc. New developers can just use HTML to add a button, and the game is now available in your browser. You don't need to choose an engine, have admin privileges, or hell for the dedicated you don't even need a computer - there are tools for web development that run in the browser itself, so you can technically use your phone if that's all you have.

Javascript is a perfectly viable language for making web games, whereas other genres are typically going to require using other more difficult languages to learn. There are countless javascript tutorials that start from 0 knowledge of programming, making it incredibly accessible to beginners.

Players are Easy to Find

Once you've finished your game and uploaded it on github pages or itch or just copied the link if you're using glitch or replit (all of which are easy to do), anyone can now play the game in their browser. This low barrier to entry has shown tremendous success in getting completely unknown developers to have thousands of plays.

The incremental games community, which mostly centers around r/incremental_games, is always looking for new games and tends to flood any new ones posted with initial players.

Having your games be played can be incredibly motivating, and the community makes it quite clear that you can expect players to play your game. These communities - both for incremental games in general as well as game-specific communities - tend to be very developer friendly as well. A lot of the developers know each other, and welcome new developers with open arms, often with dedicated channels for programming help and discussions.

Monetization

I'd like to clarify that everything I've said above mainly applies to web-based incrementals. Incremental games are also incredibly popular on mobile, but with a much different culture and community. Many mobile gamers will still participate in the web-focused community for the culture. This web-focused community has a culture that has been criticized for being "anti-monetization". Ads, IAPs, and similar forms of monetization are often criticized, mainly due to the abundance of completely non-monetized games available from hobbyist developers. There are exceptions, like paid games often being considered fine, like Increlution or Stuck in Time, or donation ware games like kittens game, but even popular games that have IAP see some level of regular criticism, like NGU Idle, Idle Skilling, or Idle Pins. A large part of this can be explained by the community being hyper-aware of the addictive) nature of this genre and its susceptibility to exploiting players.

On mobile, however, monetization is the norm and expected. If an incremental game is available on mobile, it almost certainly will be monetized, and mobile players are aware and accepting of that. Mobile incremental games, due to their addictive nature, tend to make a lot of money. It's very lucrative, and therefore these games are quite abundant on mobile storefronts.

- +.


Referenced by:Incremental SocialKronos

There are a lot of developers in the incremental games community - the genre seems to draw them in, and convert a lot of players into developers. Let's explore the reasons why this genre appeals to developers.

Incrementals are Easy to Make

Compared to other genres, incrementals have quite low expectations. You don't need to make fancy art, or music, or lay things out nicely. If you can make a button and learn the few lines of code necessary to make a number go up, you can make an incremental. This low threshold makes the genre perfect for those who are actively learning to code and haven't developed any gamedev-related skills yet.

Additionally, unlike other genres incrementals are uniquely easy to implement in a normal web page - no need to worry about rendering sprites, moving them around, implementing physics, etc. New developers can just use HTML to add a button, and the game is now available in your browser. You don't need to choose an engine, have admin privileges, or hell for the dedicated you don't even need a computer - there are tools for web development that run in the browser itself, so you can technically use your phone if that's all you have.

Javascript is a perfectly viable language for making web games, whereas other genres are typically going to require using other more difficult languages to learn. There are countless javascript tutorials that start from 0 knowledge of programming, making it incredibly accessible to beginners.

Players are Easy to Find

Once you've finished your game and uploaded it on github pages or itch or just copied the link if you're using glitch or replit (all of which are easy to do), anyone can now play the game in their browser. This low barrier to entry has shown tremendous success in getting completely unknown developers to have thousands of plays.

The incremental games community, which mostly centers around r/incremental_games, is always looking for new games and tends to flood any new ones posted with initial players.

Having your games be played can be incredibly motivating, and the community makes it quite clear that you can expect players to play your game. These communities - both for incremental games in general as well as game-specific communities - tend to be very developer friendly as well. A lot of the developers know each other, and welcome new developers with open arms, often with dedicated channels for programming help and discussions.

Monetization

I'd like to clarify that everything I've said above mainly applies to web-based incrementals. Incremental games are also incredibly popular on mobile, but with a much different culture and community. Many mobile gamers will still participate in the web-focused community for the culture. This web-focused community has a culture that has been criticized for being "anti-monetization". Ads, IAPs, and similar forms of monetization are often criticized, mainly due to the abundance of completely non-monetized games available from hobbyist developers. There are exceptions, like paid games often being considered fine, like Increlution or Stuck in Time, or donation ware games like kittens game, but even popular games that have IAP see some level of regular criticism, like NGU Idle, Idle Skilling, or Idle Pins. A large part of this can be explained by the community being hyper-aware of the addictive) nature of this genre and its susceptibility to exploiting players.

On mobile, however, monetization is the norm and expected. If an incremental game is available on mobile, it almost certainly will be monetized, and mobile players are aware and accepting of that. Mobile incremental games, due to their addictive nature, tend to make a lot of money. It's very lucrative, and therefore these games are quite abundant on mobile storefronts.

+ \ No newline at end of file diff --git a/garden/guide-to-incrementals/appeal-to-players/index.html b/garden/guide-to-incrementals/appeal-to-players/index.html index 00141e0cb..647b05a5c 100644 --- a/garden/guide-to-incrementals/appeal-to-players/index.html +++ b/garden/guide-to-incrementals/appeal-to-players/index.html @@ -6,14 +6,14 @@ Guide to Incrementals/Appeal to Players | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Guide to Incrementals/Appeal to Players

2166 words, ~12 minute read. Planted +

Skip to content

Guide to Incrementals/Appeal to Players

2166 words, ~12 minute read. Planted . Last tended to -.


Referenced by:Incremental SocialKronos

This is something that has been discussed and analyzed by many people, and to some extent, I feel like everything that can be said on the topic already has. However, a lot of these analyses are from the perspective of those with not as much experience and involvement within the genre as I'd argue would be necessary for a fully contextualized answer. I'm interested in ludology and part of that includes interpreting games as art, and to that end what constitutes a game, let alone a "good game". Incremental games are oft criticized, unfairly in my biased opinion, of not even constituting games, such as was posited by this polygon article.

Numbers Going Up

This is a very common response to why people enjoy incremental games, although it's not one I find compels me personally, and I suspect it might be a stand-in for progression) or Guide to Incrementals/What is Content?. But reportedly, some people do just like seeing big numbers. I must reiterate I suspect the actual cause is seeing big numbers in context though - if you start at 1e1000 of a currency and get to 1e1001, that isn't going to feel as satisfying as going from 1e10 to 1e100, and in any case, I don't think a button that just adds a zero to your number will feel quite satisfying - I believe its the sense of having made progress, and comparing where you are to where you started and feeling like you've earned your way here that is enjoyable.

Progression

I think a strong sense of progression is seen as very enjoyable to many players of all sorts of genres - engine builder board games, RPGs, rogue_lites_, etc. Incremental games tend to have an extremely exaggerated sense of progression, which makes them very appealing.

Meta-progression is when games have some sort of progression that persists when other progress gets lost - for example, upgrades that persist between runs of a roguelite game. These are common mechanics in incremental games - in fact, its not uncommon to have multiple of these reset mechanics nested on top of each other, each with their own meta-progression. These are satisfying to players, although they can be a bit controversial. These mechanics can often be seen as an optional crutch, and in roguelite games, players often challenge themselves to win without any meta progression. Essentially these challenges argue that meta-progression de-emphasizes player skill by replacing it with time served. Incremental games, through their exaggerated progression, eschew that possibility though - they make it impossible to beat without the meta progression systems, as the meta-progression becomes an entire chapter of the gameplay. I'd argue this does not detract from the game, however, and is actually a part of what makes incremental games, and roguelikes, enjoyable to many players: meta-progression augments the increases in skill the player is naturally gaining as they play. In effect, it's not replacing the skill increase, but exaggerating it to make it feel more real to the player.

Effortlessness

Incremental games are so easy, a lot of them even have you progress while you're not playing! Part of the appeal is being able to feel like you're making progress while doing something actually productive - multitasking, in a way. In this sense, the game is more of a fidget toy - not something to think hard about and play actively, but something to click a few buttons every so often while you're paying attention to a lecture or studying or working. Of course, not all incremental games lend themselves to being played this way - it's specifically "idle" games that work like this. These are games that take an incredibly long amount of time to see all the content, stretching it as thin as possible, but they aren't expecting you to be sitting at your device playing it the entire time. They expect you to leave and come back later to make a bit of progress and repeat the cycle.

If you look at the higher-level play of most games, you'll see them perform difficult feats with ease and speed. They'll achieve a "flow state" that takes all their knowledge and experience of the game and uses it to play the game as instinctively as possible. It's incredible to watch things like Slay the Spire speed runs or competitive DDR-likes. I'd argue the goal of a lot of games with a competitive scene is to get so good that the game becomes effortless. In that sense, a game that allows you to reach that point earlier isn't any less legitimate, but rather lowers the barrier to entry by allowing more people to get "really good" at the game. And to be clear, (most) incremental games aren't trivially easy - they, and to an extent, every game will have some level of learning and improvement over time.

Addiction

A lot of these reasons for why incremental games appeal may have reminded you of why gambling appeals to people, particularly those prone to addiction. Indeed, incremental games are quite often criticized for their similarity to a skinner box. Some have gone as far as to say incremental games as a genre are commenting that all games are skinner boxes). The argument goes that some games are not fun, but rather condition players into continuing to play without actually getting anything from the experience. When tied to real-world money this is seen as predatory, and to a lesser extent, even free games may be feeding the addictive sides of people and making them more prone to seek out gambling or micro-transaction heavy games.

While incremental games can be fun and even healthy in certain contexts, they can exacerbate video game addiction more than other genres. If you feel like playing incremental games is taking priority over other things in your life, or manipulating your sleep schedule, it may be prudent to seek help. See r/StopGaming for resources.

Since incremental games are often built on extrinsic motivations in the form of progression systems, it's hard to argue whether players continue to play because they are enjoying the gameplay, or if they are just conditioned to keep doing it because the game keeps rewarding them. Unfortunately, it can often feel like it's the latter, as there isn't typically anything compelling about the "gameplay" of clicking a button and waiting. There may be a significant overlap between those who enjoy incremental games and those who are most prone to addiction, and there are often posts on r/incremental_games about someone either struggling with or overcoming video game addiction.

Strategy

Incremental games could be considered a subset of strategy games), and inherit the appeals of strategy games. This includes the appeal of feeling like you've found a good solution to a puzzle, or that you're learning more about the game and are improving at making decisions within it.

Note that strategy games are not all the same difficulty, as well. Cookie Clicker is probably easier than Starcraft 2 (although late game may beg to differ). Plenty of incremental games can be used as evidence that "easier" strategies may have their separate appeal to harder strategy games - players like to feel smart and that they figured the game out and have optimized or mastered it, and the game being easier doesn't detract from that sense of accomplishment as much as it allows more and more users to be able to reach the point where they gain that sense.

Avoiding Staleness

Incremental games tend to have "paradigm shifts", where the gameplay changes in a meaningful way at various times throughout the progression of the game. These upset and change the gameplay loop, which helps keep them from stagnating. This constant "freshness" to the gameplay can keep players engaged for longer, compared to a game with a repetitive and static gameplay loop.

Good Game Design

Incremental games tend to show their game design "plainly", so it's more readily apparent if a game has good game design while playing, even if you're not looking for it. While different players have different preferences and might enjoy different types of games more than others, there are underlying good and bad game design principles that players will notice the effects of. To be clear, this isn't talking about stuff like big numbers being enjoyable, where I can comfortably agree to disagree with other players. They don't intrinsically make my experience better, but I'm aware of those for whom it does and I won't argue against their feelings. However, the game designer in me does feel like there are some extremely clear-cut examples of good and bad game design philosophies.

Let's start by giving an example of a mechanic I think can be easily and strongly argued is good game design. There are of course many examples, but a personal favorite of mine is how DOOM encourages aggressive gameplay by linking health drops to melee attacks. It has an intended experience it's trying to give the player - immersing themselves as DOOM guy, who would not hide behind cover when low on health - and this mechanic does a great job at encouraging and effectively teaching players to behave properly. This is in sharp contrast to shooters like Call of Duty, which have you regen health passively, encouraging players to hide behind cover and wait after getting hit. Note that I'm not arguing CoD is poorly designed, as the games have different intended experiences. I'm specifically praising DOOM for having a mechanic that does a good job at ensuring the player has that intended experience.

To contrast with an example I think is bad game design, let's talk about shields in souls-likes. This is a bit of a famous example, and I highly recommend this video essay which spends quite a good bit of time on this topic. Essentially, the argument boils down to players of earlier games in the souls games using shields too much - playing slowly, conservatively, and ultimately having less fun. Players wanted to feel safe, so they ended up playing in a way that ruined the experience for them. The developers solved this by removing shields, apart from an intentionally bad one effectively mocking the playstyle, and it did its job at getting players to play more aggressively, and often have more fun.

To bring the conversation back to incrementals, I'm incredibly opinionated on what makes a good incremental game, which I'll discuss in the game design section. Suffice it to say, incremental games rely more on good game design than other genres, due to not having much to distract from bad game design. This helps (although imperfectly - gamers are a bit too tolerant of bad game design!) well-designed games rise to the top within the genre.

Artistic Merit

The discussion of whether video games are art has resulted in a pretty universal "yes, they are", but with some games the argument may still crop up. The reason why Incremental games are sometimes questioned is due to their perceived lack of complexity. However, even setting aside the fact that if players are having fun then it's not time wasted, I think games can have artistic merit that supersedes the necessity of having (any / engaging / "deep") gameplay. Incremental games are no less legitimate of a game or the "art" label because of any lack perceived lack of depth. For what it's worth, most art can be consumed with more ease than any video game - any painting, movie, sculpture, etc.

A lot of incrementals have a narrative context that can similarly qualify them as art. Cookie Clicker is, as has been pointed out numerous times before, commenting on excess and increasing production beyond any reasonable limits - devolving into increasing production for its own sake. Indeed, a lot of incremental games are written to comment upon various concepts like capitalism or tropes in games, as discussed when defining Incrementals). However, I'd like to argue most incremental games are still art, even without any narrative context. "Art" as a concept is pretty nebulous already, but I personally like those who define it as an act of expression more than any physical result. The creator and the context within which they created the art, and any meaning they put into it, are all relevant and a part of the art itself. Most incremental games have artistic merit from things like why the creator made it, why they chose to make it an incremental game, and why they made any particular design decision. Hell, even if you play through an entire incremental game without a single thought or feeling, that very fact it elicited nothing can itself be artistic merit!

I'm not an art major, and I may be taking a somewhat extreme take on what is art and what has artistic merit, but I'd argue the overall point stands that games, and incremental games specifically, can have artistic merit, which appeals to many gamers.

- +.


Referenced by:Incremental SocialKronos

This is something that has been discussed and analyzed by many people, and to some extent, I feel like everything that can be said on the topic already has. However, a lot of these analyses are from the perspective of those with not as much experience and involvement within the genre as I'd argue would be necessary for a fully contextualized answer. I'm interested in ludology and part of that includes interpreting games as art, and to that end what constitutes a game, let alone a "good game". Incremental games are oft criticized, unfairly in my biased opinion, of not even constituting games, such as was posited by this polygon article.

Numbers Going Up

This is a very common response to why people enjoy incremental games, although it's not one I find compels me personally, and I suspect it might be a stand-in for progression) or Guide to Incrementals/What is Content?. But reportedly, some people do just like seeing big numbers. I must reiterate I suspect the actual cause is seeing big numbers in context though - if you start at 1e1000 of a currency and get to 1e1001, that isn't going to feel as satisfying as going from 1e10 to 1e100, and in any case, I don't think a button that just adds a zero to your number will feel quite satisfying - I believe its the sense of having made progress, and comparing where you are to where you started and feeling like you've earned your way here that is enjoyable.

Progression

I think a strong sense of progression is seen as very enjoyable to many players of all sorts of genres - engine builder board games, RPGs, rogue_lites_, etc. Incremental games tend to have an extremely exaggerated sense of progression, which makes them very appealing.

Meta-progression is when games have some sort of progression that persists when other progress gets lost - for example, upgrades that persist between runs of a roguelite game. These are common mechanics in incremental games - in fact, its not uncommon to have multiple of these reset mechanics nested on top of each other, each with their own meta-progression. These are satisfying to players, although they can be a bit controversial. These mechanics can often be seen as an optional crutch, and in roguelite games, players often challenge themselves to win without any meta progression. Essentially these challenges argue that meta-progression de-emphasizes player skill by replacing it with time served. Incremental games, through their exaggerated progression, eschew that possibility though - they make it impossible to beat without the meta progression systems, as the meta-progression becomes an entire chapter of the gameplay. I'd argue this does not detract from the game, however, and is actually a part of what makes incremental games, and roguelikes, enjoyable to many players: meta-progression augments the increases in skill the player is naturally gaining as they play. In effect, it's not replacing the skill increase, but exaggerating it to make it feel more real to the player.

Effortlessness

Incremental games are so easy, a lot of them even have you progress while you're not playing! Part of the appeal is being able to feel like you're making progress while doing something actually productive - multitasking, in a way. In this sense, the game is more of a fidget toy - not something to think hard about and play actively, but something to click a few buttons every so often while you're paying attention to a lecture or studying or working. Of course, not all incremental games lend themselves to being played this way - it's specifically "idle" games that work like this. These are games that take an incredibly long amount of time to see all the content, stretching it as thin as possible, but they aren't expecting you to be sitting at your device playing it the entire time. They expect you to leave and come back later to make a bit of progress and repeat the cycle.

If you look at the higher-level play of most games, you'll see them perform difficult feats with ease and speed. They'll achieve a "flow state" that takes all their knowledge and experience of the game and uses it to play the game as instinctively as possible. It's incredible to watch things like Slay the Spire speed runs or competitive DDR-likes. I'd argue the goal of a lot of games with a competitive scene is to get so good that the game becomes effortless. In that sense, a game that allows you to reach that point earlier isn't any less legitimate, but rather lowers the barrier to entry by allowing more people to get "really good" at the game. And to be clear, (most) incremental games aren't trivially easy - they, and to an extent, every game will have some level of learning and improvement over time.

Addiction

A lot of these reasons for why incremental games appeal may have reminded you of why gambling appeals to people, particularly those prone to addiction. Indeed, incremental games are quite often criticized for their similarity to a skinner box. Some have gone as far as to say incremental games as a genre are commenting that all games are skinner boxes). The argument goes that some games are not fun, but rather condition players into continuing to play without actually getting anything from the experience. When tied to real-world money this is seen as predatory, and to a lesser extent, even free games may be feeding the addictive sides of people and making them more prone to seek out gambling or micro-transaction heavy games.

While incremental games can be fun and even healthy in certain contexts, they can exacerbate video game addiction more than other genres. If you feel like playing incremental games is taking priority over other things in your life, or manipulating your sleep schedule, it may be prudent to seek help. See r/StopGaming for resources.

Since incremental games are often built on extrinsic motivations in the form of progression systems, it's hard to argue whether players continue to play because they are enjoying the gameplay, or if they are just conditioned to keep doing it because the game keeps rewarding them. Unfortunately, it can often feel like it's the latter, as there isn't typically anything compelling about the "gameplay" of clicking a button and waiting. There may be a significant overlap between those who enjoy incremental games and those who are most prone to addiction, and there are often posts on r/incremental_games about someone either struggling with or overcoming video game addiction.

Strategy

Incremental games could be considered a subset of strategy games), and inherit the appeals of strategy games. This includes the appeal of feeling like you've found a good solution to a puzzle, or that you're learning more about the game and are improving at making decisions within it.

Note that strategy games are not all the same difficulty, as well. Cookie Clicker is probably easier than Starcraft 2 (although late game may beg to differ). Plenty of incremental games can be used as evidence that "easier" strategies may have their separate appeal to harder strategy games - players like to feel smart and that they figured the game out and have optimized or mastered it, and the game being easier doesn't detract from that sense of accomplishment as much as it allows more and more users to be able to reach the point where they gain that sense.

Avoiding Staleness

Incremental games tend to have "paradigm shifts", where the gameplay changes in a meaningful way at various times throughout the progression of the game. These upset and change the gameplay loop, which helps keep them from stagnating. This constant "freshness" to the gameplay can keep players engaged for longer, compared to a game with a repetitive and static gameplay loop.

Good Game Design

Incremental games tend to show their game design "plainly", so it's more readily apparent if a game has good game design while playing, even if you're not looking for it. While different players have different preferences and might enjoy different types of games more than others, there are underlying good and bad game design principles that players will notice the effects of. To be clear, this isn't talking about stuff like big numbers being enjoyable, where I can comfortably agree to disagree with other players. They don't intrinsically make my experience better, but I'm aware of those for whom it does and I won't argue against their feelings. However, the game designer in me does feel like there are some extremely clear-cut examples of good and bad game design philosophies.

Let's start by giving an example of a mechanic I think can be easily and strongly argued is good game design. There are of course many examples, but a personal favorite of mine is how DOOM encourages aggressive gameplay by linking health drops to melee attacks. It has an intended experience it's trying to give the player - immersing themselves as DOOM guy, who would not hide behind cover when low on health - and this mechanic does a great job at encouraging and effectively teaching players to behave properly. This is in sharp contrast to shooters like Call of Duty, which have you regen health passively, encouraging players to hide behind cover and wait after getting hit. Note that I'm not arguing CoD is poorly designed, as the games have different intended experiences. I'm specifically praising DOOM for having a mechanic that does a good job at ensuring the player has that intended experience.

To contrast with an example I think is bad game design, let's talk about shields in souls-likes. This is a bit of a famous example, and I highly recommend this video essay which spends quite a good bit of time on this topic. Essentially, the argument boils down to players of earlier games in the souls games using shields too much - playing slowly, conservatively, and ultimately having less fun. Players wanted to feel safe, so they ended up playing in a way that ruined the experience for them. The developers solved this by removing shields, apart from an intentionally bad one effectively mocking the playstyle, and it did its job at getting players to play more aggressively, and often have more fun.

To bring the conversation back to incrementals, I'm incredibly opinionated on what makes a good incremental game, which I'll discuss in the game design section. Suffice it to say, incremental games rely more on good game design than other genres, due to not having much to distract from bad game design. This helps (although imperfectly - gamers are a bit too tolerant of bad game design!) well-designed games rise to the top within the genre.

Artistic Merit

The discussion of whether video games are art has resulted in a pretty universal "yes, they are", but with some games the argument may still crop up. The reason why Incremental games are sometimes questioned is due to their perceived lack of complexity. However, even setting aside the fact that if players are having fun then it's not time wasted, I think games can have artistic merit that supersedes the necessity of having (any / engaging / "deep") gameplay. Incremental games are no less legitimate of a game or the "art" label because of any lack perceived lack of depth. For what it's worth, most art can be consumed with more ease than any video game - any painting, movie, sculpture, etc.

A lot of incrementals have a narrative context that can similarly qualify them as art. Cookie Clicker is, as has been pointed out numerous times before, commenting on excess and increasing production beyond any reasonable limits - devolving into increasing production for its own sake. Indeed, a lot of incremental games are written to comment upon various concepts like capitalism or tropes in games, as discussed when defining Incrementals). However, I'd like to argue most incremental games are still art, even without any narrative context. "Art" as a concept is pretty nebulous already, but I personally like those who define it as an act of expression more than any physical result. The creator and the context within which they created the art, and any meaning they put into it, are all relevant and a part of the art itself. Most incremental games have artistic merit from things like why the creator made it, why they chose to make it an incremental game, and why they made any particular design decision. Hell, even if you play through an entire incremental game without a single thought or feeling, that very fact it elicited nothing can itself be artistic merit!

I'm not an art major, and I may be taking a somewhat extreme take on what is art and what has artistic merit, but I'd argue the overall point stands that games, and incremental games specifically, can have artistic merit, which appeals to many gamers.

+ \ No newline at end of file diff --git a/garden/guide-to-incrementals/defining-the-genre/index.html b/garden/guide-to-incrementals/defining-the-genre/index.html index 4173e8bec..a0dcf6afd 100644 --- a/garden/guide-to-incrementals/defining-the-genre/index.html +++ b/garden/guide-to-incrementals/defining-the-genre/index.html @@ -6,14 +6,14 @@ Guide to Incrementals/Defining the Genre | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Guide to Incrementals/Defining the Genre

4048 words, ~22 minute read. Planted +

Skip to content

Guide to Incrementals/Defining the Genre

4048 words, ~22 minute read. Planted . Last tended to -.


Referenced by:Incremental SocialKronos

Video games are placed into genres for a variety of reasons. They can give a mental shorthand to set the player's expectations up, they can help a game market itself by its similarities to other, already popular games, and honestly, people just love categorization for its own sake. For this guide, it's important to define the genre so it is clear what games it's even talking about.

This poses a problem. Genres, being Social Constructs, suffer from the usual issues social constructs have of being vague and shifting over time. "Incremental", in particular, is a horribly vague way to define games. Most games have numbers going up in some form or another. We need a more specific definition - similar to how "strategy" can't just mean any game with any amount of strategy because that would be most games. What specifically differentiates incremental games from the rest?

"Incremental" implies it's a genre defined by a game mechanic, but all those game mechanics it could imply exist in many other games. Having a skill tree or upgrades doesn't make you incremental, and if a reset mechanic is all it takes then every roguelite would be an incremental as well. So clearly there's more to it than that - what makes an incremental an incremental?

I'd like to go over a couple of popular suggestions I've seen on defining the genre here. I have my personal preferences and will state them here, but I don't think there's a truly perfect answer.

BTW, if this article made you realize discourse around defining genres is actually a really interesting, even fascinating, topic, I recommend this video essay: Who Shot Guybrush Threepwood? | Genre and the Adventure Game.

Disclaimer: I mostly play incremental games on my computer, and my definitions will be heavily biased towards the games I'm familiar with.

Incrementals vs Idlers vs Clickers

Oftentimes people refer to this genre as idle games and/or clicker games. You'll even find a trend of oxymoronic game titles that contain both terms. "Incremental games" is the umbrella term both those terms fall under. However, I'd like to argue that not only is it better to just use the term "incremental games", but calling them "idle games" or "clicker games" is wrong. Almost universally, these terms are used interchangeably to refer to the same kind of game, where you start the game click spamming and eventually automate the process. Frankly, that kind of game deserves neither title, and the genre of incremental games has trended away from ever requiring click spamming, as it's a bad mechanic, anyways.

While these games do span a spectrum of how active it requires you to be, and sorting games by that metric can be useful for those looking for a particular experience, the borders of when an incremental game counts as an "idler" is too blurry for the term to be useful. "Incremental games" may not be a great descriptive term for the genre (hence this many thousands of words long page on defining what the genre even is), but it's strictly better than calling them "idler" or "clicker" games. This guide will always use the term "incremental games" unless quoting someone else, as it is the term you typically see on all modern games in the genre.

Incrementals as Parodies

Let's start with one of the most interesting definitions of incremental games. Incremental games appear to be distilled versions of games or genres, "revealing" the naked game design at the core of these games or genres not unlike how parodies comment upon their source material.

To understand what that means, think of how a casino uses skinner boxes to emotionally manipulate its customers to keep playing, but "dressing" up the skinner box with tons of stimuli to hide that ultimately the goal is to condition you into coming back compulsively. The idea that incremental games are parodies means taking the stance that at some level all games are similarly manipulating you, giving dopamine rewards in a way that manipulates you to keep playing while not necessarily giving you any value or fulfillment. Incremental games, then, are any games that plainly display the skinner box, and the manipulative core of the game, at the forefront of the experience.

While incremental games can be fun and even healthy in certain contexts, they can exacerbate video game addiction more than other genres. If you feel like playing incremental games is taking priority over other things in your life, or manipulating your sleep schedule, it may be prudent to seek help. See r/StopGaming for resources.

This "undressing" tends to go hand in hand with a reduced focus on aesthetics, often just printing the game state directly to the screen as text. This makes incremental games much easier to develop, particularly for those with programming skills but not art skills, but that's a tangent for why Incremental Games Guide to Incrementals/Appeal to Developers.

Before I continue, I'd like to make my stance clear that I love games and incremental games, and do not think they should be considered inherently bad or manipulative with the above logic. Skinner boxes are just a way of manipulating behavior via rewards. The games are still fun - that's the reward! I'd believe the real criticism here is that it is "empty fun", or "empty dopamine", that doesn't offer any additional value or sense of fulfillment. I don't think that's inherently bad in moderation, although it can become a problem if the game is manipulating you for profit-seeking, or if you play the game to the detriment of the other parts of your life.

Another interpretation of incremental games as parodies comes from several mainstream incremental games that are also parodies of capitalism, such as cookie clicker and adventure capitalist. It's a very common framework for incremental games to portray the ever-increasing numbers as an insatiable hunger for resources, like the ones observed within capitalism. Therefore, these games are used as evidence that the genre as a whole is about parody and commentary.

Popular videos on incremental games that portray the genre as parodies are Why Idle games make good satire, and how it was ruined. and Bad Game Design - Clicker Games. You may also be interested in this response to the latter video from a fan of incremental games: BadGood Game Design - Clicker Games.

I think that this definition ultimately ascribes a motive to the genre as a whole that only happens to apply to some of the more mainstream titles. There certainly are incremental games commenting on different things, including the genre itself as in the case of The Prestige Tree Classic, The Ascension Tree, or Omega Layers, but certainly not all. And of course, not all games that comment on something or parody something are incremental games! Additionally, a very large majority of incremental games are mobile games using these manipulative strategies to get players to spend as much money as possible - hell, Adventure Capitalist is ostensibly a critique on capitalism but features microtransactions and gameplay that manipulates you into buying them! These profit-seeking incremental games certainly belong within the genre but are hardly parodies when they too use manipulation to serve their interests. Also, from my own anecdotal experience, those who use this definition seem to do so from a fairly surface-level familiarity with the genre, and often in the context of criticizing the genre or the fans thereof.

Incrementals as NGU

Another broad definition often used is that incremental games are games where the focus of the game is "numbers going up". This definition proposes that other genres simply use increasing numbers as a means to an end, but incremental games uniquely only care about the numbers themselves going up. Put another way, it implies there should be no narrative justification for the numbers going up other than "why shouldn't they be going up?"

While this definition is common because it feels easy to understand, it is difficult to formally define. Often phrases are used to describe games using this framework, such as having an "exaggerated sense of progression" or "big" numbers. These terms are vague and don't demonstrate an actual threshold between non-incrementals and incrementals. Most games have a sense of progression, so when is it "exaggerated"? How big are "big" numbers? Most notably, RPGs that are typically not considered incrementals will often pass this definition.

Additionally, a lot of incrementals tend to have some theme guiding the gameplay, or at least the names of mechanics. This makes the line blurred between when numbers are going up for their own sake versus for a contextual reason. I believe this point is best illustrated that, while most RPGs are not considered incremental games, there is a sub-genre of "incremental RPGs" that typically relates to RPGs that perform combat automatically. This definition of incremental games does not support RPGs and "incremental RPGs" being on distinct sides of the line if the only difference between them is manual vs automatic combat.

Incrementals as Strategies

This is a rarer interpretation, but there are similarities between incremental games and strategy games, implying incrementals might just be a sub-genre of strategy games. By this approach, incremental games would be defined by their relation to strategy games, and how they involve player strategy. Incremental games are often large optimization problems - above all else, the actual gameplay the player is performing is deciding what to do next. The consequences of wrong decisions are typically more lenient in incremental games - such as just not making optimal progress - but they certainly get complex.

So if we accept the premise that incrementals could fall under strategy, we still need to define what makes a strategy game an incremental versus some other strategy sub-genre. This is a bit tricky due to one particular sub-genre of strategy games: Factory Builders.

Factory builders, such as Factorio or Satisfactory, are games about gaining ever increasing resources, optimizing production, and expanding more and more. That... sounds pretty similar, doesn't it? In fact, there's been some debate on whether factory builders would fall under the "incremental" umbrella. I think it's safe to say the two are certainly related, and probably have quite a bit of overlap in playerbase.

Roguelites as Incrementals?

Earlier on, I mentioned reset mechanics shouldn't be used in the definition because that could make all roguelites incrementals... But what if it does? A lot of incrementals can be described as games with a strong sense of progression, often with layers of meta-progression. Roguelites fit that bill to a T. What would make roguelites not incremental? I honestly don't think there's a good explanation here, but many fans of incremental games will state they do believe the two genres to be unrelated, even if there's a significant overlap between their player bases due to having similar appealing traits.

At this point, it'd be appropriate to consider what part of the definition of roguelites precludes them from also being incrementals, but that reveals a new problem: What are roguelites? They're usually defined as rogue_likes with meta-progression, but that just pushes the problem back a step: Incrementals aren't the only genre to have difficulties defining themselves, it seems! Roguelikes are another genre where the community argues over the formal definition of their genre, although that means we can borrow from their process of coming to a consensus, and maybe come across a viable definition for incremental games.

The Berlin Interpretation

By far the most popular way of defining roguelikes is the "Berlin Interpretation", which acknowledged the diversity of games within the genre and argued the definition should not be based on any ideals about what the genre ought to be, but rather defined by "its canon". They argued there are a handful of games that can be used to define the canon for roguelikes, and from those games, a list of factors can be derived to determine a game's "roguelikeness". The more factors a game has, the more of a roguelike it is. This strategy is very lenient, allowing a game to not present any specific factor so long as it shows enough, and accounts for the blurriness of any genre definition by not explicitly stating how many factors a game must have to qualify as a definite roguelike.

I believe this strategy for defining genres can be applied to other genres as well. A handful of games can be argued to be the incremental games canon, and a list of factors derived from them can be used to judge any game based on its "incrementalness". I'll propose such a canon and list of factors here, but by no means should it be considered the end-all-be-all.

Note: The "Temple of the roguelike", an authority within the genre, has since replaced the Berlin Interpretation with a new set of factors here: https://blog.roguetemple.com/what-is-a-traditional-roguelike/

A Modern Incremental Games Canon

Alright, time to get controversial. Up til now, I've been trying my best to stay objective and analytical, but now it's time to start making some opinionated decisions. I've created a list of games I think could be justified in making up a modern incremental games canon.

Before I mention the list, let's establish how I got to this list. First off, I'm really focusing on building a definition of the genre today, so I prefer modern games over traditional ones. A canon of culturally or historically significant titles to the genre would give a different list. Keep in mind the original Berlin interpretation (and the temple's update to it) were trying to define "traditional roguelikes", which is not my objective here. Building a canon that aims to trace the history of the genre is still valid and useful.

I'm also trying to ensure I pick a large breadth of incremental games, so I'm going to approach the list as a list of archetypes, with a single game to represent it but with other titles mentioned as other examples. This approach places each archetype as equally important, even if one only has a couple entries. Besides the impracticality of a canon that just includes every game, it'd be very biased towards games with large modding communities like Cookie Clicker or The Prestige Tree.

With all that behind us, here is a list of games I think could justifiably make up a Modern Incremental Games Canon:

  • Dodecadragons

    This game represents incremental games with many prestige layers that often have rapid resets and automate lower layers as more get unlocked. Other examples could also include The Prestige Tree, Really Grass Cutting Incremental Classic, Distance Incremental, or the massive modding community TPT has. A lot of the games I've personally worked on fall in this group, like Advent Incremental.

  • Evolve Idle

    This game represents incremental games with few prestige layers, very slow resets, and a focus on resource management. Typically involve some sort of worker allocation. Other examples would be Kitten's Game, Shark Game, or Magic Research.

  • (the) Gnorp Apologue

    This game represents incremental games with a central mechanic that gets added to by various other mechanics. All the mechanics remain relevant throughout the game, with different ones contributing most over time. Other examples include Nodebuster and To the Core. A lot of traditional games also fall in this archetype by having characters or buildings you level up, that each contribute additively to gaining the primary resources. These include Cookie Clicker, Clicker Heroes, and Realm Grinder. In a way, that makes the modern titles mentioned in this archetype the spiritual successors of those traditional games, and exemplifies how the genre has changed.

  • Idle Momentum

    This game represents incremental games that include polynomial growth as a central mechanic that is then built upon. Other examples include Antimatter Dimensions, Swarm Simulator, and Derivative Clicker.

  • Melvor Idle

    This game represents incremental games that are essentially a genre blend between incremental games and RPGs. Compared to other types of RPGs, these games have a focus on progressing while idle. Other examples would be IdleOn and a very large amount of mobile RPGs.

  • Stuck in Time

    This game represents incremental games that include a reset mechanic where there are pre-defined decisions being made during the course of the run. There's typically a concept of a playable character, whose actions are being "queued up" during a run, and these runs become longer or otherwise more productive as the game progresses. There are a lot of examples of this genre, including Cavernous II, Increlution, Progress Knight, Idle Loops, and Groundhog Life.

  • Universal Paperclips

    This game represents incremental games that involve several phases of completely distinct gameplay that fully replace the previous, called "paradigm shifts". Prestige layers are also often paradigm shifts, but this game represents paradigm shifts that are not reset mechanics but still transform the gameplay. Other examples would be Crank or A Dark Room. Spore would be an example that's not typically considered an incremental.

  • Unnamed Space Idle

    This game represents incremental games that focus on unlocking many different independent progression systems that boost each other, and all remain relevant throughout the course of the game. Other examples include NGU Idle, Anti-Idle, Idle Skilling, and Idle Wizard.

It may look like I've just shifted the problem down a level - rather than defining the genre, I'm now defining a bunch of sub-genres. However, the methods used here for defining the canon, and my attempt at ensuring a breadth of games by determining distinct archetypes, is just my approach. This list is additionally biased towards games I'm more familiar with, which will differ person to person. The only hard and fast rule is that every game on the list should be nearly universally accepted as an incremental game. So long as you do that, the factors should be relatively similar, although ofc individuals will still likely have small differences, as is the nature of socially constructed definitions.

Naturally this canon is a perpetual work-in-progress. I'm currently a bit uncertain about the distinctions between the evolve idle, melvor idle, and unnamed space idle archetypes. I could see those being rewritten as two or even a single archetype.

Unfolding

There are several related concepts mentioned in the canon - unfolding, prestige layers, and paradigm shifts. Unfolding is the umbrella term which includes the other two, and is clearly the highest possible value factor for an incremental. It's so common that for a while people referred to incrementals that exhibit this trait as "unfolding" games, to the point of trying to replace the term incremental due to their popularity.

There are many reasons for the appeal of unfolding mechanics. Oftentimes each mechanic builds on top of the existing mechanics, increasing the complexity of the game in steps so the player can follow along. In fact, sometimes the older mechanics will be entirely phased out (e.g. by automating them), so the complexity of the game remains roughly equal throughout the game. In any case, adding new mechanics regularly provides a sense of mystery, with the player anticipating what will happen next. They shake up the gameplay before it gets too stale - allowing the game to entertain for longer before the sense of Guide to Incrementals/What is Content? dissipates. Of the canon games selected above, I would argue every single one contains unfolding to some degree.

I should take a moment to say that while I'm hyping up this specific factor, we cannot just reduce the genre definition to "does it introduce new mechanics over time". Many games have paradigm shifts that are not incremental, so it's just an indicator of incrementalness. Every single canon game may show that it's common amongst incremental games, but could just as easily indicate that they're common in games in general.

High-Value Factors

I won't take as long to discuss the high and low-value factors, as you've already seen most of them brought up earlier on this page. As a reminder, a game does NOT need all of these to be an incremental game, but these are factors that each indicate a strong possibility the game is an incremental, so having several of these means they probably are. These factors apply to most of the canon incremental games.

"Pure UI" Display. Incrementals typically have a data-driven interface of the game state - there isn't a visual representation of the entities within the game. The interface resembles what might be a control panel in another genre, with a focus on numbers, buttons, and readouts rather than animated sprites or scenes. Even when there are visual elements, like item icons or simple enemy images, the player's main interaction is with non-diegetic, UI-focused components rather than immersive game visuals.

Reduced Consequences. Incrementals tend to have reduced repurcussions for misplaying. They very rarely have fail states, where often the largest consequence is simply not progressing - never losing progress.

Optimization Problems. The predominant gameplay of incrementals is typically solving optimization problems, from deciding which purchase to save up for to reasoning and deciding between different mutually exclusive options the game presents.

Resource Management. Incrementals tend to have a lot of resources within the game to keep track of.

Low-Value Factors

These are low-value factors, meaning they aren't as strongly correlated with incremental games. Incremental games may have none of these, and non-incrementals may have several of these - if a game only has low-value factors, they're probably not an incremental.

Fast Numeric Growth. Numbers in incremental games tend to grow faster than in other genres. There are more instances of superlinear growth. The larger the numbers get, the stronger of a signal this factor is.

Automation. As an incremental game progresses, the player often no longer has to deal with earlier mechanics, by having them either happen automatically or otherwise be replaced with an alternative that requires less player interaction.

Goal-Oriented. Incrementals are often heavily reliant on extrinsic motivation to guide the player. Typically this is through some sort of in-game goal to work towards, such as a certain amount of a resource being required to unlock or purchase something new.

Waiting is a Mechanic. In incremental games, the player may come across times where there is no action they can take, and the game will progress automatically instead. The player must wait for some amount of this automatic progress to occur before they can resume interaction with the game.

Are Roguelites Incrementals?

Having made our variation of the Berlin Interpretation for incremental games, we can compare it to the Berlin Interpretation to determine if there's enough overlap that any game that "passes" the Berlin Interpretation would also pass the incremental variant. That is to say, whether any roguelite would also be considered an incremental game.

The meta-progression of an incremental game could arguably be considered a paradigm shift, and certainly adds some resource management. Goal-oriented would probably also apply. I think anything other than those would be a stretch, and in my opinion that just isn't enough to qualify. To be totally honest, I was never expecting to conclude otherwise though 😉

Sub-Genres

There are some trends in incremental games that go beyond just being a commonly used mechanic, such that they deeply affect the rest of the game design. To a degree each of the games in the canon could arguably be part of distinct sub-genres, but I think these 4 deserve specific mentions:

Loops games are a sub-genre defined by having a core mechanic related to a loop, where the player is deciding the actions taken per loop. Notable examples include Idle Loops, Stuck in Time, Cavernous II, and Increlution. You may also argue Groundhog Life and Progress Knight fall into this sub-genre.

ITRTG-like games are a sub-genre defined by having a core mechanic based on clearing increasingly difficult battles and often tend to have a lot of different mechanics to become progressively stronger. Notable examples include Idling to Rule the Gods, NGU Idle, and Wizard and Minion Idle.

Polynomial Growth games are a sub-genre defined by having a core mechanic related to a higher degree polynomial. Notable examples include the base layer of Antimatter Dimensions and Swarm Simulator.

Upgrades Games is a category popular on flash games websites that featured games focused on buying upgrades that would allow you to attain more currency in some sort of minigame that would earn you more money to buy more upgrades, which I'd argue now belong under the fold of incremental games. Notable examples include the Learn to Fly series and Upgrade Complete.

Cultivation RPGs are a genre of games, books, and anime popular in China that center around being in a fantasy world with characters getting stronger over time. While few of them get translated into English, a fan of incremental games may find the available games interesting.

- +.


Referenced by:Incremental SocialKronos

Video games are placed into genres for a variety of reasons. They can give a mental shorthand to set the player's expectations up, they can help a game market itself by its similarities to other, already popular games, and honestly, people just love categorization for its own sake. For this guide, it's important to define the genre so it is clear what games it's even talking about.

This poses a problem. Genres, being Social Constructs, suffer from the usual issues social constructs have of being vague and shifting over time. "Incremental", in particular, is a horribly vague way to define games. Most games have numbers going up in some form or another. We need a more specific definition - similar to how "strategy" can't just mean any game with any amount of strategy because that would be most games. What specifically differentiates incremental games from the rest?

"Incremental" implies it's a genre defined by a game mechanic, but all those game mechanics it could imply exist in many other games. Having a skill tree or upgrades doesn't make you incremental, and if a reset mechanic is all it takes then every roguelite would be an incremental as well. So clearly there's more to it than that - what makes an incremental an incremental?

I'd like to go over a couple of popular suggestions I've seen on defining the genre here. I have my personal preferences and will state them here, but I don't think there's a truly perfect answer.

BTW, if this article made you realize discourse around defining genres is actually a really interesting, even fascinating, topic, I recommend this video essay: Who Shot Guybrush Threepwood? | Genre and the Adventure Game.

Disclaimer: I mostly play incremental games on my computer, and my definitions will be heavily biased towards the games I'm familiar with.

Incrementals vs Idlers vs Clickers

Oftentimes people refer to this genre as idle games and/or clicker games. You'll even find a trend of oxymoronic game titles that contain both terms. "Incremental games" is the umbrella term both those terms fall under. However, I'd like to argue that not only is it better to just use the term "incremental games", but calling them "idle games" or "clicker games" is wrong. Almost universally, these terms are used interchangeably to refer to the same kind of game, where you start the game click spamming and eventually automate the process. Frankly, that kind of game deserves neither title, and the genre of incremental games has trended away from ever requiring click spamming, as it's a bad mechanic, anyways.

While these games do span a spectrum of how active it requires you to be, and sorting games by that metric can be useful for those looking for a particular experience, the borders of when an incremental game counts as an "idler" is too blurry for the term to be useful. "Incremental games" may not be a great descriptive term for the genre (hence this many thousands of words long page on defining what the genre even is), but it's strictly better than calling them "idler" or "clicker" games. This guide will always use the term "incremental games" unless quoting someone else, as it is the term you typically see on all modern games in the genre.

Incrementals as Parodies

Let's start with one of the most interesting definitions of incremental games. Incremental games appear to be distilled versions of games or genres, "revealing" the naked game design at the core of these games or genres not unlike how parodies comment upon their source material.

To understand what that means, think of how a casino uses skinner boxes to emotionally manipulate its customers to keep playing, but "dressing" up the skinner box with tons of stimuli to hide that ultimately the goal is to condition you into coming back compulsively. The idea that incremental games are parodies means taking the stance that at some level all games are similarly manipulating you, giving dopamine rewards in a way that manipulates you to keep playing while not necessarily giving you any value or fulfillment. Incremental games, then, are any games that plainly display the skinner box, and the manipulative core of the game, at the forefront of the experience.

While incremental games can be fun and even healthy in certain contexts, they can exacerbate video game addiction more than other genres. If you feel like playing incremental games is taking priority over other things in your life, or manipulating your sleep schedule, it may be prudent to seek help. See r/StopGaming for resources.

This "undressing" tends to go hand in hand with a reduced focus on aesthetics, often just printing the game state directly to the screen as text. This makes incremental games much easier to develop, particularly for those with programming skills but not art skills, but that's a tangent for why Incremental Games Guide to Incrementals/Appeal to Developers.

Before I continue, I'd like to make my stance clear that I love games and incremental games, and do not think they should be considered inherently bad or manipulative with the above logic. Skinner boxes are just a way of manipulating behavior via rewards. The games are still fun - that's the reward! I'd believe the real criticism here is that it is "empty fun", or "empty dopamine", that doesn't offer any additional value or sense of fulfillment. I don't think that's inherently bad in moderation, although it can become a problem if the game is manipulating you for profit-seeking, or if you play the game to the detriment of the other parts of your life.

Another interpretation of incremental games as parodies comes from several mainstream incremental games that are also parodies of capitalism, such as cookie clicker and adventure capitalist. It's a very common framework for incremental games to portray the ever-increasing numbers as an insatiable hunger for resources, like the ones observed within capitalism. Therefore, these games are used as evidence that the genre as a whole is about parody and commentary.

Popular videos on incremental games that portray the genre as parodies are Why Idle games make good satire, and how it was ruined. and Bad Game Design - Clicker Games. You may also be interested in this response to the latter video from a fan of incremental games: BadGood Game Design - Clicker Games.

I think that this definition ultimately ascribes a motive to the genre as a whole that only happens to apply to some of the more mainstream titles. There certainly are incremental games commenting on different things, including the genre itself as in the case of The Prestige Tree Classic, The Ascension Tree, or Omega Layers, but certainly not all. And of course, not all games that comment on something or parody something are incremental games! Additionally, a very large majority of incremental games are mobile games using these manipulative strategies to get players to spend as much money as possible - hell, Adventure Capitalist is ostensibly a critique on capitalism but features microtransactions and gameplay that manipulates you into buying them! These profit-seeking incremental games certainly belong within the genre but are hardly parodies when they too use manipulation to serve their interests. Also, from my own anecdotal experience, those who use this definition seem to do so from a fairly surface-level familiarity with the genre, and often in the context of criticizing the genre or the fans thereof.

Incrementals as NGU

Another broad definition often used is that incremental games are games where the focus of the game is "numbers going up". This definition proposes that other genres simply use increasing numbers as a means to an end, but incremental games uniquely only care about the numbers themselves going up. Put another way, it implies there should be no narrative justification for the numbers going up other than "why shouldn't they be going up?"

While this definition is common because it feels easy to understand, it is difficult to formally define. Often phrases are used to describe games using this framework, such as having an "exaggerated sense of progression" or "big" numbers. These terms are vague and don't demonstrate an actual threshold between non-incrementals and incrementals. Most games have a sense of progression, so when is it "exaggerated"? How big are "big" numbers? Most notably, RPGs that are typically not considered incrementals will often pass this definition.

Additionally, a lot of incrementals tend to have some theme guiding the gameplay, or at least the names of mechanics. This makes the line blurred between when numbers are going up for their own sake versus for a contextual reason. I believe this point is best illustrated that, while most RPGs are not considered incremental games, there is a sub-genre of "incremental RPGs" that typically relates to RPGs that perform combat automatically. This definition of incremental games does not support RPGs and "incremental RPGs" being on distinct sides of the line if the only difference between them is manual vs automatic combat.

Incrementals as Strategies

This is a rarer interpretation, but there are similarities between incremental games and strategy games, implying incrementals might just be a sub-genre of strategy games. By this approach, incremental games would be defined by their relation to strategy games, and how they involve player strategy. Incremental games are often large optimization problems - above all else, the actual gameplay the player is performing is deciding what to do next. The consequences of wrong decisions are typically more lenient in incremental games - such as just not making optimal progress - but they certainly get complex.

So if we accept the premise that incrementals could fall under strategy, we still need to define what makes a strategy game an incremental versus some other strategy sub-genre. This is a bit tricky due to one particular sub-genre of strategy games: Factory Builders.

Factory builders, such as Factorio or Satisfactory, are games about gaining ever increasing resources, optimizing production, and expanding more and more. That... sounds pretty similar, doesn't it? In fact, there's been some debate on whether factory builders would fall under the "incremental" umbrella. I think it's safe to say the two are certainly related, and probably have quite a bit of overlap in playerbase.

Roguelites as Incrementals?

Earlier on, I mentioned reset mechanics shouldn't be used in the definition because that could make all roguelites incrementals... But what if it does? A lot of incrementals can be described as games with a strong sense of progression, often with layers of meta-progression. Roguelites fit that bill to a T. What would make roguelites not incremental? I honestly don't think there's a good explanation here, but many fans of incremental games will state they do believe the two genres to be unrelated, even if there's a significant overlap between their player bases due to having similar appealing traits.

At this point, it'd be appropriate to consider what part of the definition of roguelites precludes them from also being incrementals, but that reveals a new problem: What are roguelites? They're usually defined as rogue_likes with meta-progression, but that just pushes the problem back a step: Incrementals aren't the only genre to have difficulties defining themselves, it seems! Roguelikes are another genre where the community argues over the formal definition of their genre, although that means we can borrow from their process of coming to a consensus, and maybe come across a viable definition for incremental games.

The Berlin Interpretation

By far the most popular way of defining roguelikes is the "Berlin Interpretation", which acknowledged the diversity of games within the genre and argued the definition should not be based on any ideals about what the genre ought to be, but rather defined by "its canon". They argued there are a handful of games that can be used to define the canon for roguelikes, and from those games, a list of factors can be derived to determine a game's "roguelikeness". The more factors a game has, the more of a roguelike it is. This strategy is very lenient, allowing a game to not present any specific factor so long as it shows enough, and accounts for the blurriness of any genre definition by not explicitly stating how many factors a game must have to qualify as a definite roguelike.

I believe this strategy for defining genres can be applied to other genres as well. A handful of games can be argued to be the incremental games canon, and a list of factors derived from them can be used to judge any game based on its "incrementalness". I'll propose such a canon and list of factors here, but by no means should it be considered the end-all-be-all.

Note: The "Temple of the roguelike", an authority within the genre, has since replaced the Berlin Interpretation with a new set of factors here: https://blog.roguetemple.com/what-is-a-traditional-roguelike/

A Modern Incremental Games Canon

Alright, time to get controversial. Up til now, I've been trying my best to stay objective and analytical, but now it's time to start making some opinionated decisions. I've created a list of games I think could be justified in making up a modern incremental games canon.

Before I mention the list, let's establish how I got to this list. First off, I'm really focusing on building a definition of the genre today, so I prefer modern games over traditional ones. A canon of culturally or historically significant titles to the genre would give a different list. Keep in mind the original Berlin interpretation (and the temple's update to it) were trying to define "traditional roguelikes", which is not my objective here. Building a canon that aims to trace the history of the genre is still valid and useful.

I'm also trying to ensure I pick a large breadth of incremental games, so I'm going to approach the list as a list of archetypes, with a single game to represent it but with other titles mentioned as other examples. This approach places each archetype as equally important, even if one only has a couple entries. Besides the impracticality of a canon that just includes every game, it'd be very biased towards games with large modding communities like Cookie Clicker or The Prestige Tree.

With all that behind us, here is a list of games I think could justifiably make up a Modern Incremental Games Canon:

  • Dodecadragons

    This game represents incremental games with many prestige layers that often have rapid resets and automate lower layers as more get unlocked. Other examples could also include The Prestige Tree, Really Grass Cutting Incremental Classic, Distance Incremental, or the massive modding community TPT has. A lot of the games I've personally worked on fall in this group, like Advent Incremental.

  • Evolve Idle

    This game represents incremental games with few prestige layers, very slow resets, and a focus on resource management. Typically involve some sort of worker allocation. Other examples would be Kitten's Game, Shark Game, or Magic Research.

  • (the) Gnorp Apologue

    This game represents incremental games with a central mechanic that gets added to by various other mechanics. All the mechanics remain relevant throughout the game, with different ones contributing most over time. Other examples include Nodebuster and To the Core. A lot of traditional games also fall in this archetype by having characters or buildings you level up, that each contribute additively to gaining the primary resources. These include Cookie Clicker, Clicker Heroes, and Realm Grinder. In a way, that makes the modern titles mentioned in this archetype the spiritual successors of those traditional games, and exemplifies how the genre has changed.

  • Idle Momentum

    This game represents incremental games that include polynomial growth as a central mechanic that is then built upon. Other examples include Antimatter Dimensions, Swarm Simulator, and Derivative Clicker.

  • Melvor Idle

    This game represents incremental games that are essentially a genre blend between incremental games and RPGs. Compared to other types of RPGs, these games have a focus on progressing while idle. Other examples would be IdleOn and a very large amount of mobile RPGs.

  • Stuck in Time

    This game represents incremental games that include a reset mechanic where there are pre-defined decisions being made during the course of the run. There's typically a concept of a playable character, whose actions are being "queued up" during a run, and these runs become longer or otherwise more productive as the game progresses. There are a lot of examples of this genre, including Cavernous II, Increlution, Progress Knight, Idle Loops, and Groundhog Life.

  • Universal Paperclips

    This game represents incremental games that involve several phases of completely distinct gameplay that fully replace the previous, called "paradigm shifts". Prestige layers are also often paradigm shifts, but this game represents paradigm shifts that are not reset mechanics but still transform the gameplay. Other examples would be Crank or A Dark Room. Spore would be an example that's not typically considered an incremental.

  • Unnamed Space Idle

    This game represents incremental games that focus on unlocking many different independent progression systems that boost each other, and all remain relevant throughout the course of the game. Other examples include NGU Idle, Anti-Idle, Idle Skilling, and Idle Wizard.

It may look like I've just shifted the problem down a level - rather than defining the genre, I'm now defining a bunch of sub-genres. However, the methods used here for defining the canon, and my attempt at ensuring a breadth of games by determining distinct archetypes, is just my approach. This list is additionally biased towards games I'm more familiar with, which will differ person to person. The only hard and fast rule is that every game on the list should be nearly universally accepted as an incremental game. So long as you do that, the factors should be relatively similar, although ofc individuals will still likely have small differences, as is the nature of socially constructed definitions.

Naturally this canon is a perpetual work-in-progress. I'm currently a bit uncertain about the distinctions between the evolve idle, melvor idle, and unnamed space idle archetypes. I could see those being rewritten as two or even a single archetype.

Unfolding

There are several related concepts mentioned in the canon - unfolding, prestige layers, and paradigm shifts. Unfolding is the umbrella term which includes the other two, and is clearly the highest possible value factor for an incremental. It's so common that for a while people referred to incrementals that exhibit this trait as "unfolding" games, to the point of trying to replace the term incremental due to their popularity.

There are many reasons for the appeal of unfolding mechanics. Oftentimes each mechanic builds on top of the existing mechanics, increasing the complexity of the game in steps so the player can follow along. In fact, sometimes the older mechanics will be entirely phased out (e.g. by automating them), so the complexity of the game remains roughly equal throughout the game. In any case, adding new mechanics regularly provides a sense of mystery, with the player anticipating what will happen next. They shake up the gameplay before it gets too stale - allowing the game to entertain for longer before the sense of Guide to Incrementals/What is Content? dissipates. Of the canon games selected above, I would argue every single one contains unfolding to some degree.

I should take a moment to say that while I'm hyping up this specific factor, we cannot just reduce the genre definition to "does it introduce new mechanics over time". Many games have paradigm shifts that are not incremental, so it's just an indicator of incrementalness. Every single canon game may show that it's common amongst incremental games, but could just as easily indicate that they're common in games in general.

High-Value Factors

I won't take as long to discuss the high and low-value factors, as you've already seen most of them brought up earlier on this page. As a reminder, a game does NOT need all of these to be an incremental game, but these are factors that each indicate a strong possibility the game is an incremental, so having several of these means they probably are. These factors apply to most of the canon incremental games.

"Pure UI" Display. Incrementals typically have a data-driven interface of the game state - there isn't a visual representation of the entities within the game. The interface resembles what might be a control panel in another genre, with a focus on numbers, buttons, and readouts rather than animated sprites or scenes. Even when there are visual elements, like item icons or simple enemy images, the player's main interaction is with non-diegetic, UI-focused components rather than immersive game visuals.

Reduced Consequences. Incrementals tend to have reduced repurcussions for misplaying. They very rarely have fail states, where often the largest consequence is simply not progressing - never losing progress.

Optimization Problems. The predominant gameplay of incrementals is typically solving optimization problems, from deciding which purchase to save up for to reasoning and deciding between different mutually exclusive options the game presents.

Resource Management. Incrementals tend to have a lot of resources within the game to keep track of.

Low-Value Factors

These are low-value factors, meaning they aren't as strongly correlated with incremental games. Incremental games may have none of these, and non-incrementals may have several of these - if a game only has low-value factors, they're probably not an incremental.

Fast Numeric Growth. Numbers in incremental games tend to grow faster than in other genres. There are more instances of superlinear growth. The larger the numbers get, the stronger of a signal this factor is.

Automation. As an incremental game progresses, the player often no longer has to deal with earlier mechanics, by having them either happen automatically or otherwise be replaced with an alternative that requires less player interaction.

Goal-Oriented. Incrementals are often heavily reliant on extrinsic motivation to guide the player. Typically this is through some sort of in-game goal to work towards, such as a certain amount of a resource being required to unlock or purchase something new.

Waiting is a Mechanic. In incremental games, the player may come across times where there is no action they can take, and the game will progress automatically instead. The player must wait for some amount of this automatic progress to occur before they can resume interaction with the game.

Are Roguelites Incrementals?

Having made our variation of the Berlin Interpretation for incremental games, we can compare it to the Berlin Interpretation to determine if there's enough overlap that any game that "passes" the Berlin Interpretation would also pass the incremental variant. That is to say, whether any roguelite would also be considered an incremental game.

The meta-progression of an incremental game could arguably be considered a paradigm shift, and certainly adds some resource management. Goal-oriented would probably also apply. I think anything other than those would be a stretch, and in my opinion that just isn't enough to qualify. To be totally honest, I was never expecting to conclude otherwise though 😉

Sub-Genres

There are some trends in incremental games that go beyond just being a commonly used mechanic, such that they deeply affect the rest of the game design. To a degree each of the games in the canon could arguably be part of distinct sub-genres, but I think these 4 deserve specific mentions:

Loops games are a sub-genre defined by having a core mechanic related to a loop, where the player is deciding the actions taken per loop. Notable examples include Idle Loops, Stuck in Time, Cavernous II, and Increlution. You may also argue Groundhog Life and Progress Knight fall into this sub-genre.

ITRTG-like games are a sub-genre defined by having a core mechanic based on clearing increasingly difficult battles and often tend to have a lot of different mechanics to become progressively stronger. Notable examples include Idling to Rule the Gods, NGU Idle, and Wizard and Minion Idle.

Polynomial Growth games are a sub-genre defined by having a core mechanic related to a higher degree polynomial. Notable examples include the base layer of Antimatter Dimensions and Swarm Simulator.

Upgrades Games is a category popular on flash games websites that featured games focused on buying upgrades that would allow you to attain more currency in some sort of minigame that would earn you more money to buy more upgrades, which I'd argue now belong under the fold of incremental games. Notable examples include the Learn to Fly series and Upgrade Complete.

Cultivation RPGs are a genre of games, books, and anime popular in China that center around being in a fantasy world with characters getting stronger over time. While few of them get translated into English, a fan of incremental games may find the available games interesting.

+ \ No newline at end of file diff --git a/garden/guide-to-incrementals/index.html b/garden/guide-to-incrementals/index.html index 69378badf..d1ec3171b 100644 --- a/garden/guide-to-incrementals/index.html +++ b/garden/guide-to-incrementals/index.html @@ -6,14 +6,14 @@ Guide to Incrementals | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Guide to Incrementals

230 words, ~1 minute read. Planted +

Skip to content

Guide to Incrementals

230 words, ~1 minute read. Planted . Last tended to -.


Referenced by:My Personal Website

This is a comprehensive guide to Incremental Games, a genre of video games. It will explore defining the genre, why it's appealing, and how to design and build your own incremental game. Along the way will be interactive examples, snippets from other creators, and relevant material to contextualize everything.

Note: This is an incomplete document. I want to keep adding opinions and opposing views from other incremental games developers, and add interactive examples to illustrate various points regarding game design and balancing. Consider this a living document - and see the changelog at the end.

Why am I making this?

That's a good question! What authority do I have to be making this guide? I haven't made the best incremental games, nor the most incremental games, certainly not the most popular ones either. But I do have some formal education in game development, know a lot of incremental game devs (as well as other game devs), and have a passionate interest in ludology, classifying genres, etc. I've also made a couple of incremental games) myself.

If you have any additional questions about my credentials or anything on this site, feel free to reach out!

Ludology

Making an Incremental

- +.


Referenced by:My Personal Website

This is a comprehensive guide to Incremental Games, a genre of video games. It will explore defining the genre, why it's appealing, and how to design and build your own incremental game. Along the way will be interactive examples, snippets from other creators, and relevant material to contextualize everything.

Note: This is an incomplete document. I want to keep adding opinions and opposing views from other incremental games developers, and add interactive examples to illustrate various points regarding game design and balancing. Consider this a living document - and see the changelog at the end.

Why am I making this?

That's a good question! What authority do I have to be making this guide? I haven't made the best incremental games, nor the most incremental games, certainly not the most popular ones either. But I do have some formal education in game development, know a lot of incremental game devs (as well as other game devs), and have a passionate interest in ludology, classifying genres, etc. I've also made a couple of incremental games) myself.

If you have any additional questions about my credentials or anything on this site, feel free to reach out!

Ludology

Making an Incremental

+ \ No newline at end of file diff --git a/garden/guide-to-incrementals/navigating-criticism/index.html b/garden/guide-to-incrementals/navigating-criticism/index.html index ff3d90a9b..f0c1d90c8 100644 --- a/garden/guide-to-incrementals/navigating-criticism/index.html +++ b/garden/guide-to-incrementals/navigating-criticism/index.html @@ -6,14 +6,14 @@ Guide to Incrementals/Navigating Criticism | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Guide to Incrementals/Navigating Criticism

747 words, ~4 minute read. Planted +

Skip to content

Guide to Incrementals/Navigating Criticism

747 words, ~4 minute read. Planted . Last tended to -.


Referenced by:Incremental SocialKronos

Developing games is fun and exciting and teaches a lot of wonderful skills - I enthusiastically encourage anyone with an interest in game development to try it out - and incremental games are a wonderful way to get started. However, there are many challenges young and inexperienced developers have to face, and I think the hardest one - harder than coding, debugging, balancing, etc. - is handling criticism. When you put your heart and soul into a game it is natural to feel very vulnerable. While I think there's a lot communities can do to ensure they're welcoming, positive and constructive with their criticisms, inevitably you will eventually read some, and potentially a lot, of comments that can deeply affect you. No one is immune to this, from young incremental game developers to the largest content creators you can think of. That's why it's important to be able to process and navigate criticism, because ultimately collecting feedback is essential to the journey to becoming a better developer. On this page, we'll explore how to embrace criticism, grow from it, and continue to post your games publicly with confidence.

Reading Feedback

Game development is a skill that takes time and practice to get truly great at. Criticism and other constructive feedback are vital to continually improving. It's useful to look at the criticism as solely a tool for improving this game and future games - that is to say, it should never be used against you as a person. Insults towards the developer(s) themselves are never okay and should not be allowed within whatever community you're sharing your works in. If you do come across a comment you interpret as an attack upon your person, you should report it. For other negative comments, try not to internalize them; instead, focus on improving the game. By distancing your own identity from your work emotionally, you can better analyze the game and use the feedback to your advantage.

Not all feedback is made equal, and you don't need to feel compelled to read and obey every piece of feedback you receive. Learn to distinguish between constructive feedback and unhelpful comments. Constructive feedback typically offers specific suggestions for improvement, while unhelpful comments are often vague or hurtful. Prioritize the former and disregard the latter. That said, most feedback you get will not be from game developers, so take specific suggestions with a grain of salt. Determine the actual problem they're experiencing, and design what you believe the best solution to that problem would be, regardless if that's the specific solution the player asked for. And keep in mind, due to different player preferences you'll never satisfy everyone, and you don't need to. Ultimately if even just you find the game fun, then that's a success.

Seeking Feedback

When deciding where to share your game, consider the type of players you anticipate getting, and the kind of feedback you can anticipate receiving. Different communities will have different levels of support for learning developers, and certain communities may prefer certain types of games or mechanics. It's important to get a diverse set of feedback focused on players you think will enjoy the specific game you're making.

Collecting feedback from other game developers is incredibly helpful. They've trained themselves to recognize good and bad game design and how to articulate the differences, and from my experience are much more likely to leave positive and constructive comments since they've been in your shoes before! They understand the struggles and can offer guidance and emotional support.

Responding to Feedback

Negative feedback can naturally feel like an attack, and it's okay to get angry. However, lashing back is never the appropriate response. It's best to cool off IRL, and keep in mind all the positive comments you've received. There's a concept in Psychology called negative bias that explains how negative feedback tends to stick with us much more prominently than positive feedback, so it's useful to regularly remind yourself of all the positive feedback you've received. Celebrate your successes, no matter how small they may seem - getting a game to a state you can publicly share it with people is an accomplishment in and of itself!

Remember your passion and your initial reasons for getting into game development. The journey will have its ups and downs, but staying true to your vision and passion will keep you motivated.

- +.


Referenced by:Incremental SocialKronos

Developing games is fun and exciting and teaches a lot of wonderful skills - I enthusiastically encourage anyone with an interest in game development to try it out - and incremental games are a wonderful way to get started. However, there are many challenges young and inexperienced developers have to face, and I think the hardest one - harder than coding, debugging, balancing, etc. - is handling criticism. When you put your heart and soul into a game it is natural to feel very vulnerable. While I think there's a lot communities can do to ensure they're welcoming, positive and constructive with their criticisms, inevitably you will eventually read some, and potentially a lot, of comments that can deeply affect you. No one is immune to this, from young incremental game developers to the largest content creators you can think of. That's why it's important to be able to process and navigate criticism, because ultimately collecting feedback is essential to the journey to becoming a better developer. On this page, we'll explore how to embrace criticism, grow from it, and continue to post your games publicly with confidence.

Reading Feedback

Game development is a skill that takes time and practice to get truly great at. Criticism and other constructive feedback are vital to continually improving. It's useful to look at the criticism as solely a tool for improving this game and future games - that is to say, it should never be used against you as a person. Insults towards the developer(s) themselves are never okay and should not be allowed within whatever community you're sharing your works in. If you do come across a comment you interpret as an attack upon your person, you should report it. For other negative comments, try not to internalize them; instead, focus on improving the game. By distancing your own identity from your work emotionally, you can better analyze the game and use the feedback to your advantage.

Not all feedback is made equal, and you don't need to feel compelled to read and obey every piece of feedback you receive. Learn to distinguish between constructive feedback and unhelpful comments. Constructive feedback typically offers specific suggestions for improvement, while unhelpful comments are often vague or hurtful. Prioritize the former and disregard the latter. That said, most feedback you get will not be from game developers, so take specific suggestions with a grain of salt. Determine the actual problem they're experiencing, and design what you believe the best solution to that problem would be, regardless if that's the specific solution the player asked for. And keep in mind, due to different player preferences you'll never satisfy everyone, and you don't need to. Ultimately if even just you find the game fun, then that's a success.

Seeking Feedback

When deciding where to share your game, consider the type of players you anticipate getting, and the kind of feedback you can anticipate receiving. Different communities will have different levels of support for learning developers, and certain communities may prefer certain types of games or mechanics. It's important to get a diverse set of feedback focused on players you think will enjoy the specific game you're making.

Collecting feedback from other game developers is incredibly helpful. They've trained themselves to recognize good and bad game design and how to articulate the differences, and from my experience are much more likely to leave positive and constructive comments since they've been in your shoes before! They understand the struggles and can offer guidance and emotional support.

Responding to Feedback

Negative feedback can naturally feel like an attack, and it's okay to get angry. However, lashing back is never the appropriate response. It's best to cool off IRL, and keep in mind all the positive comments you've received. There's a concept in Psychology called negative bias that explains how negative feedback tends to stick with us much more prominently than positive feedback, so it's useful to regularly remind yourself of all the positive feedback you've received. Celebrate your successes, no matter how small they may seem - getting a game to a state you can publicly share it with people is an accomplishment in and of itself!

Remember your passion and your initial reasons for getting into game development. The journey will have its ups and downs, but staying true to your vision and passion will keep you motivated.

+ \ No newline at end of file diff --git a/garden/guide-to-incrementals/what-is-content/index.html b/garden/guide-to-incrementals/what-is-content/index.html index 3fa400be6..528f944f4 100644 --- a/garden/guide-to-incrementals/what-is-content/index.html +++ b/garden/guide-to-incrementals/what-is-content/index.html @@ -6,14 +6,14 @@ Guide to Incrementals/What is Content? | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Guide to Incrementals/What is Content?

2272 words, ~12 minute read. Planted +

Skip to content

Guide to Incrementals/What is Content?

2272 words, ~12 minute read. Planted . Last tended to -.


Referenced by:Incremental SocialKronos

If you've been in the incremental games community for any amount of time, you'll quickly find the number one thing players want is content. They want as much of it as possible! The most popular incremental games have tons of content, so they just keep stretching on and on and on, introducing mechanic after mechanic, and players love it. In fact, players seem to value the amount of content over the quality of any specific content. However, there's a bit of a lack of understanding concerning what content is, and I'd like to explore what counts as content, and how we measure it. As a baseline definition, I think "content" can just be described as the parts of the game that engage the player, but to truly understand it we need to contextualize what that means and how it affects the gameplay experience.

To clarify the purpose of this page, my goal is not to get (too) nitpicky or to attack games with "low content". There's nothing wrong with short / low-content games - I'm quite a big fan of those games myself! This is mostly targeted toward those who ask for content and settle for "long" games, and those who want to provide content but want to make sure they're not just artificially inflating the game. Ultimately, I suppose the goal is to just reduce the amount of artificially inflated content for the sake of having a "longer" game.

Interaction

I think it should be a fairly non-controversial opinion that time spent solely waiting should not count towards content. That is not including the time reading various effects or making decisions in your head, but rather time spent waiting for a condition to be met so you can re-engage with the game.

That is not to say games should necessarily try to minimize this time. Plenty of games lead towards more infrequent interaction and still get popular. In fact, these games appeal to many gamers who want to have something to check up on in between bursts of working on some other activity. These games seem to have fallen slightly out of fashion amongst modern incremental games, but they're still fully valid. The point I'm trying to make here is just that this time is not content. As an extreme example, a game with no interactions and just a counter that goes up every second could safely be said to have 0 content beyond the time it takes to understand what's going on. If it has a list of "goals" to hit, then the time understanding those goals and a short time after achieving each one could be considered content, but not the idle times in between.

Let's take a look at the opposite end of the spectrum - interaction that is so frequent as to become mindless. This is any mechanic where you need to spam-click something to progress. This may be a more controversial take, but I do not believe this constitutes content either. It does not engage the player, because each consecutive click blends together and they do not individually change the gameplay experience. That is to say, a single click and 100 clicks are not meaningfully different in terms of engaging the player. I'd go as far as to say clicking 100 times would be actively worse, as it's artificially delaying the next piece of actual content, alongside the issues of accessibility and potentially causing RSI.

Repeatable Purchases

Imagine an entity in a game that you can purchase multiple times, each time it performs the same thing but for a higher cost. These are incredibly common, from the buildings in cookie clicker to the units in swarm sim to the IP and EP multipliers in antimatter dimensions. However, how much content is each specific purchase? Is it content beyond the first purchase? Does it have diminishing returns? What if you are oscillating between two different repeatable purchases? How much content is lost when you automate) away a repeatable purchase?

I don't want to take too harsh a stance against repeatable purchases. They're useful tools and can be used in a myriad of interesting ways. I feel they do become "stale" or less meaningful content over time, and this happens exponentially quickly the more frequently it can be purchased. A classic example that I believe goes too far is the IP/EP multipliers in Antimatter Dimensions. I would go as far as to say they are a chore and do not provide any meaningful content after you've bought them a couple of times. It's a method for inflating numbers (effectively making every OOM a 5x step instead of 10x), that punishes the player progression-wise whenever they forget to max it again, and eventually gets automated away as a reward to the player for making enough progress.

Just to voice the other side of this argument, Acamaeda defended the IP multiplier as giving the player a "good" upgrade every OOM. I can understand that to a point and need to clarify I'm mainly criticizing IP/EP multipliers after they've been introduced for a while. In fact, I would defend the multipliers for a short while after they're introduced using the same logic I would use to defend normal dimensions as repeatable purchases, at least pre-infinity. There's "content" to be had in looking at what dimensions will become affordable next, and then choosing which to buy amongst those. The IP/EP multipliers, early into infinity or eternity respectively, provide another option that gets put into that mental queue of things to buy with each OOM reached - although the optimal order is often quite trivial and not particularly engaging.

The IP/EP multipliers are not the only repeatable purchase in antimatter dimensions I take offense to. The time dimensions are also a series of repeatable purchases, that are all so similar and static that it doesn't take long before you never need to put any thought into buying them, how much you're buying at once, or the order you buy them in - you just press max all and move on. The entire tab could've been just the max all button and it would not have made a difference beyond the start of the eternity layer. The normal dimensions technically have this problem as well, but since you're constantly getting antimatter the order feels like it has a larger impact and it's more meaningful content, right up until they're automated away. Infinity dimensions are a compromise between the two, so I'm highlighting time dimensions here as the most egregious.

Following Instructions

We're getting more and more controversial as we go along! Let's talk about how linear content is not content now (in some circumstances). A trend in incremental games is adding difficulty by adding a web of effects that abstract the true change you can expect from any specific purchase or decision you make. If a game is both linear and sufficiently abstracts the effect of player decisions, then the player will no longer be engaging with the content - they'll simply be clicking on things as they become available. This isn't necessarily a bad thing, as plenty of players don't mind this style of gameplay, but I'd argue once you reach a point where players don't bother reading the effects, those interactions are no longer truly content. Note that unlike the previous qualifiers mentioned, this qualifier is based on the player, and therefore subjective. In effect, it's a spectrum where the more complicated the web of effects becomes, the more likely it is to disengage the player.

This over-complicatedness leading to disengaging the player can also happen from non-linear gameplay. If the web of effects becomes sufficiently complicated and finding the optimal progression route too time-consuming to discover, players will seek out guides from other players who've completed the game. The second they do this, the game effectively becomes linearly following the instructions of the guide and all the above criticisms apply. Similarly to as before, though, this is a spectrum and not everyone will seek out a guide at the same level of difficulty.

Automation

Automation is a staple of the genre, but it has certain implications for the design of the game. Why, when new content is introduced, must the older content be automated away - why is it a chore and it feels rewarding to not have to do it again? Why does the new mechanic have such appeal if we know it too will just be automated away later on, and we'll be happy when that happens? It honestly begs the question of why this framework of introducing content and automating the old content is even enjoyable - and nearly nonexistent in other genres. You're not going to reach a point in a platformer game where they just automate the jumping part - that's the core mechanic! Instead, platformers either add new mechanics that build on the core mechanic or at least re-contextualize the core mechanic. However, in incremental games new content very frequently means replacing older content, as opposed to augmenting it.

Admittedly, the above paragraph ignores the obvious answer that separates incremental games in this regard. These mechanics become chores as their frequency increases. The frequency increases to give a sense of progression, and automation is seen as a reward because it now manages what was becoming unmanageable. The new content then comes in and continues the loop to give a stronger sense of progression. That's all good and a fine justification for automating content instead of building upon the base mechanic. It's also much easier to design, as each layer essentially lets you start over instead of needing to think of ideas that conform to the original core mechanic.

So, what's the problem? Even if this trend is justified and easy to implement, there are some other effects it has on the game design. First off, and this is probably a neutral point, incremental games with this cycle of replacing old mechanics with new ones trend towards more and more abstract and further away from any narrative throughline as they add layers. There are only so many justifications for resetting progress, so if a game wants to have several of these layers they're inevitably going to become generic or increasingly loosely associated with the original content. It's most unfortunate, in my opinion when an interesting or innovative core mechanic gets fully automated once a generic "prestige" layer is unlocked.

A recent example is Really Grass Cutting Incremental, an incremental game about cutting grass (although I'm really criticizing the Roblox game it's based on). Except, it doesn't continue to be about cutting grass. After you buy enough upgrades to increase your grass cutting and level up sufficiently you "prestige", an abstract term that in this case means you reset all your progress to get some currency to buy upgrades that do the same things as the original upgrades, but these won't reset on future prestiges. You'll eventually be able to "crystallize", which means you reset all your progress to get some currency to buy upgrades that do the same things as the original upgrades (and a couple of new ones) and won't reset on future crystallizes. Fine. You'll progress a bit, complete some challenges, and finally get to... grasshop? Grasshopping is this mechanic where you reset all your progress to get some resource that isn't for buying upgrades - this time you just unlock different modifiers on everything based on their amount. You may have gotten the point by now, but there are also "steelie" resets which give you steel for some reason, before unlocking a factory with various machines - none of which are directly tied to cutting grass, and start gathering things like oil and reset for rocket parts and reset to go to space and so on and so on. Throughout all of this there is absolutely no narrative justification or throughline for the direction the game is going, or why cutting grass is still relevant when we're collecting things like rocket parts. I may be going a little hard on GCI, but it is far from alone.

Ending the Game

Incremental games do not often have a planned out narrative or ending,, such that each content update is approached as its own unit of narrative and gameplay. This prevents content updates from wrapping up the game nicely - it always has to leave something open for another content layer; be it another mechanic, reset layer, etc. This cycle will continue until the updates just stop, at which point the game will just have an unsatisfying conclusion that will never get the next thing it was supposed to be leading into. This reminds me of a Leonardo Da Vinci quote about how Art is Never Complete:

Art is never finished, only abandoned. - Leonardo Da Vinci

For what its worth, there are exceptions here (including several of My Projects). I believe this practice is actually fairly reasonable, considering how many incremental game developers are learning game design and programming - keeping the scope small and expanding if it still interests you is a great way to keep learning without letting things like perfectionism or sunk cost fallacies get in the way.

Tips for Developers

If you're a developer, by this point you should have a pretty decent idea of how to create "true" content in your game. Here are some other specific tips I'd suggest:

An upgrade that simply unlocks another upgrade trivially isn't content. However, many games have an upgrade that just unlocks a feature, which then has a wait or other requirements before it can be used. Try to make sure when you unlock a feature, there is immediately something to do with the feature - for example, perhaps give them a small amount of the new currency it unlocks, if applicable.

If you don't have a large web of effects, and can definitively say the impact of a purchase is to multiply the gain of the cost currency by N, and the next purchase costs N times the amount of that same currency, then this purchase effectively made no difference and it may have made more sense to just go directly to the next upgrade. That said, having effects based on things like the number of purchases made will quickly invalidate this tip.

- +.


Referenced by:Incremental SocialKronos

If you've been in the incremental games community for any amount of time, you'll quickly find the number one thing players want is content. They want as much of it as possible! The most popular incremental games have tons of content, so they just keep stretching on and on and on, introducing mechanic after mechanic, and players love it. In fact, players seem to value the amount of content over the quality of any specific content. However, there's a bit of a lack of understanding concerning what content is, and I'd like to explore what counts as content, and how we measure it. As a baseline definition, I think "content" can just be described as the parts of the game that engage the player, but to truly understand it we need to contextualize what that means and how it affects the gameplay experience.

To clarify the purpose of this page, my goal is not to get (too) nitpicky or to attack games with "low content". There's nothing wrong with short / low-content games - I'm quite a big fan of those games myself! This is mostly targeted toward those who ask for content and settle for "long" games, and those who want to provide content but want to make sure they're not just artificially inflating the game. Ultimately, I suppose the goal is to just reduce the amount of artificially inflated content for the sake of having a "longer" game.

Interaction

I think it should be a fairly non-controversial opinion that time spent solely waiting should not count towards content. That is not including the time reading various effects or making decisions in your head, but rather time spent waiting for a condition to be met so you can re-engage with the game.

That is not to say games should necessarily try to minimize this time. Plenty of games lead towards more infrequent interaction and still get popular. In fact, these games appeal to many gamers who want to have something to check up on in between bursts of working on some other activity. These games seem to have fallen slightly out of fashion amongst modern incremental games, but they're still fully valid. The point I'm trying to make here is just that this time is not content. As an extreme example, a game with no interactions and just a counter that goes up every second could safely be said to have 0 content beyond the time it takes to understand what's going on. If it has a list of "goals" to hit, then the time understanding those goals and a short time after achieving each one could be considered content, but not the idle times in between.

Let's take a look at the opposite end of the spectrum - interaction that is so frequent as to become mindless. This is any mechanic where you need to spam-click something to progress. This may be a more controversial take, but I do not believe this constitutes content either. It does not engage the player, because each consecutive click blends together and they do not individually change the gameplay experience. That is to say, a single click and 100 clicks are not meaningfully different in terms of engaging the player. I'd go as far as to say clicking 100 times would be actively worse, as it's artificially delaying the next piece of actual content, alongside the issues of accessibility and potentially causing RSI.

Repeatable Purchases

Imagine an entity in a game that you can purchase multiple times, each time it performs the same thing but for a higher cost. These are incredibly common, from the buildings in cookie clicker to the units in swarm sim to the IP and EP multipliers in antimatter dimensions. However, how much content is each specific purchase? Is it content beyond the first purchase? Does it have diminishing returns? What if you are oscillating between two different repeatable purchases? How much content is lost when you automate) away a repeatable purchase?

I don't want to take too harsh a stance against repeatable purchases. They're useful tools and can be used in a myriad of interesting ways. I feel they do become "stale" or less meaningful content over time, and this happens exponentially quickly the more frequently it can be purchased. A classic example that I believe goes too far is the IP/EP multipliers in Antimatter Dimensions. I would go as far as to say they are a chore and do not provide any meaningful content after you've bought them a couple of times. It's a method for inflating numbers (effectively making every OOM a 5x step instead of 10x), that punishes the player progression-wise whenever they forget to max it again, and eventually gets automated away as a reward to the player for making enough progress.

Just to voice the other side of this argument, Acamaeda defended the IP multiplier as giving the player a "good" upgrade every OOM. I can understand that to a point and need to clarify I'm mainly criticizing IP/EP multipliers after they've been introduced for a while. In fact, I would defend the multipliers for a short while after they're introduced using the same logic I would use to defend normal dimensions as repeatable purchases, at least pre-infinity. There's "content" to be had in looking at what dimensions will become affordable next, and then choosing which to buy amongst those. The IP/EP multipliers, early into infinity or eternity respectively, provide another option that gets put into that mental queue of things to buy with each OOM reached - although the optimal order is often quite trivial and not particularly engaging.

The IP/EP multipliers are not the only repeatable purchase in antimatter dimensions I take offense to. The time dimensions are also a series of repeatable purchases, that are all so similar and static that it doesn't take long before you never need to put any thought into buying them, how much you're buying at once, or the order you buy them in - you just press max all and move on. The entire tab could've been just the max all button and it would not have made a difference beyond the start of the eternity layer. The normal dimensions technically have this problem as well, but since you're constantly getting antimatter the order feels like it has a larger impact and it's more meaningful content, right up until they're automated away. Infinity dimensions are a compromise between the two, so I'm highlighting time dimensions here as the most egregious.

Following Instructions

We're getting more and more controversial as we go along! Let's talk about how linear content is not content now (in some circumstances). A trend in incremental games is adding difficulty by adding a web of effects that abstract the true change you can expect from any specific purchase or decision you make. If a game is both linear and sufficiently abstracts the effect of player decisions, then the player will no longer be engaging with the content - they'll simply be clicking on things as they become available. This isn't necessarily a bad thing, as plenty of players don't mind this style of gameplay, but I'd argue once you reach a point where players don't bother reading the effects, those interactions are no longer truly content. Note that unlike the previous qualifiers mentioned, this qualifier is based on the player, and therefore subjective. In effect, it's a spectrum where the more complicated the web of effects becomes, the more likely it is to disengage the player.

This over-complicatedness leading to disengaging the player can also happen from non-linear gameplay. If the web of effects becomes sufficiently complicated and finding the optimal progression route too time-consuming to discover, players will seek out guides from other players who've completed the game. The second they do this, the game effectively becomes linearly following the instructions of the guide and all the above criticisms apply. Similarly to as before, though, this is a spectrum and not everyone will seek out a guide at the same level of difficulty.

Automation

Automation is a staple of the genre, but it has certain implications for the design of the game. Why, when new content is introduced, must the older content be automated away - why is it a chore and it feels rewarding to not have to do it again? Why does the new mechanic have such appeal if we know it too will just be automated away later on, and we'll be happy when that happens? It honestly begs the question of why this framework of introducing content and automating the old content is even enjoyable - and nearly nonexistent in other genres. You're not going to reach a point in a platformer game where they just automate the jumping part - that's the core mechanic! Instead, platformers either add new mechanics that build on the core mechanic or at least re-contextualize the core mechanic. However, in incremental games new content very frequently means replacing older content, as opposed to augmenting it.

Admittedly, the above paragraph ignores the obvious answer that separates incremental games in this regard. These mechanics become chores as their frequency increases. The frequency increases to give a sense of progression, and automation is seen as a reward because it now manages what was becoming unmanageable. The new content then comes in and continues the loop to give a stronger sense of progression. That's all good and a fine justification for automating content instead of building upon the base mechanic. It's also much easier to design, as each layer essentially lets you start over instead of needing to think of ideas that conform to the original core mechanic.

So, what's the problem? Even if this trend is justified and easy to implement, there are some other effects it has on the game design. First off, and this is probably a neutral point, incremental games with this cycle of replacing old mechanics with new ones trend towards more and more abstract and further away from any narrative throughline as they add layers. There are only so many justifications for resetting progress, so if a game wants to have several of these layers they're inevitably going to become generic or increasingly loosely associated with the original content. It's most unfortunate, in my opinion when an interesting or innovative core mechanic gets fully automated once a generic "prestige" layer is unlocked.

A recent example is Really Grass Cutting Incremental, an incremental game about cutting grass (although I'm really criticizing the Roblox game it's based on). Except, it doesn't continue to be about cutting grass. After you buy enough upgrades to increase your grass cutting and level up sufficiently you "prestige", an abstract term that in this case means you reset all your progress to get some currency to buy upgrades that do the same things as the original upgrades, but these won't reset on future prestiges. You'll eventually be able to "crystallize", which means you reset all your progress to get some currency to buy upgrades that do the same things as the original upgrades (and a couple of new ones) and won't reset on future crystallizes. Fine. You'll progress a bit, complete some challenges, and finally get to... grasshop? Grasshopping is this mechanic where you reset all your progress to get some resource that isn't for buying upgrades - this time you just unlock different modifiers on everything based on their amount. You may have gotten the point by now, but there are also "steelie" resets which give you steel for some reason, before unlocking a factory with various machines - none of which are directly tied to cutting grass, and start gathering things like oil and reset for rocket parts and reset to go to space and so on and so on. Throughout all of this there is absolutely no narrative justification or throughline for the direction the game is going, or why cutting grass is still relevant when we're collecting things like rocket parts. I may be going a little hard on GCI, but it is far from alone.

Ending the Game

Incremental games do not often have a planned out narrative or ending,, such that each content update is approached as its own unit of narrative and gameplay. This prevents content updates from wrapping up the game nicely - it always has to leave something open for another content layer; be it another mechanic, reset layer, etc. This cycle will continue until the updates just stop, at which point the game will just have an unsatisfying conclusion that will never get the next thing it was supposed to be leading into. This reminds me of a Leonardo Da Vinci quote about how Art is Never Complete:

Art is never finished, only abandoned. - Leonardo Da Vinci

For what its worth, there are exceptions here (including several of My Projects). I believe this practice is actually fairly reasonable, considering how many incremental game developers are learning game design and programming - keeping the scope small and expanding if it still interests you is a great way to keep learning without letting things like perfectionism or sunk cost fallacies get in the way.

Tips for Developers

If you're a developer, by this point you should have a pretty decent idea of how to create "true" content in your game. Here are some other specific tips I'd suggest:

An upgrade that simply unlocks another upgrade trivially isn't content. However, many games have an upgrade that just unlocks a feature, which then has a wait or other requirements before it can be used. Try to make sure when you unlock a feature, there is immediately something to do with the feature - for example, perhaps give them a small amount of the new currency it unlocks, if applicable.

If you don't have a large web of effects, and can definitively say the impact of a purchase is to multiply the gain of the cost currency by N, and the next purchase costs N times the amount of that same currency, then this purchase effectively made no difference and it may have made more sense to just go directly to the next upgrade. That said, having effects based on things like the number of purchases made will quickly invalidate this tip.

+ \ No newline at end of file diff --git a/garden/imperialism/index.html b/garden/imperialism/index.html index fc21e77de..4b7c00ad9 100644 --- a/garden/imperialism/index.html +++ b/garden/imperialism/index.html @@ -6,14 +6,14 @@ Imperialism | The Paper Pilot - + - + - - - + + + @@ -53,9 +53,9 @@ -
Skip to content

Imperialism

770 words, ~4 minute read. Planted -.


Referenced by:LeftismMy Political Beliefs

Imperialism refers to how, after all the survivable land in the world was claimed by various countries (as part of colonialism), a country - or empire - must spread its influence over new territory at cost of existing influences over that territory. Typically this has meant land being transferred, either militarily or diplomatically.

Imperialism and Capitalism

Lenin wrote an influential pamphlet over his interpretation of imperialism, called "Imperialism, the Highest Stage of Capitalism". He argued imperialism was inextricably linked with capitalism, and that the driving force of imperialism was corporations gaining control over natural resources to use for profit, and to improve their position relative to opposing powers. An imperialist war, such as the ones the US has fought in the Middle East, serve both the interests of US oil companies as well as the US itself for its position relative to other imperialist powers. This view has been supported by modern leftist scholars like Michael Parenti in his book Face of Imperialism: Responsibility-Taking in the Political World.

In effect, imperialism has been used to delay resolving the contradiction between the need to expand and the physical limits of the globe. This contradiction cannot be fully resolved under a capitalist system, which requires the need to expand infinitely. Therefore, fighting imperialism means fighting capitalism. Removing power from corporations and banks largely nullifies the reasons for imperialism and is the best path towards global peace.

US Imperialism

The size of the US empire is not obvious just by looking at a map of the world, due to its reliance on economic influence and soft power. The US also imperializes through its remaining colonies, proxy wars, and foreign military bases. Second thought has a good introductory video on how significant some of those influences are in How The US Took Over The World.

A lot of these conflicts abroad are done in the open, such as the conflicts part of the war on terror. In this case the government needs to justify to its citizens going to war, which you'll typically see happen regardless of who's in charge. This is a process called manufactured consent, as described by Herman and Chomsky in Manufacturing Consent: The Political Economy of the Mass Media, although it is not perfect and the US has a history of anti-war protest movements. The vietnam war was our first televised war and had anti war protests even escalate into riots. Today through social media the impact of war is more accessible than ever before, and the Israel-Palestine conflict has had one of the largest anti-war movements yet, although still not as large as Vietnam.

While there are several imperialist powers in the world, the US is a particularly influential one that I, as an American citizen, have the most personal interest in stopping. I believe if the US moved towards socialism the overall influence of capitalism in the world would diminish so thoroughly that it would only further decline into non-existence. This would affect not only the prosperity of the world but save many lives as well: Western imperialism has caused 50-55 million deaths since WW2 as claimed by Andre Vltchek in On western terror, and US-backed conflicts show no sign of stopping so long as capitalist interests remain.

Impact of Imperialism on the Development of the Global South

The global south refers to a collection of countries that are under-developed compared to the "global north", and have historically been victims of colonialism and imperialism. Today, the global south makes up 90% of global labor but only receives 21% of globally produced value, according to Jason Hickel et al in Unequal exchange of labour in the world economy. Jason has previously calculated that the global north extracted $242 trillion in value from the global south between 1990 and 2015 alone, despite only returning 1/30th of that in the form of foreign aid, in Imperialist appropriation in the world economy: Drain from the global South through unequal exchange, 1990–2015.

It's worth noting that Hickel is discussing all of the global north, not just the US, but US corporations make heavy use of exploitation by underpaying workers without any form of representation for the exploited or assistance in modernizing these countries ("catching up" developmentally). They allow corporations to act with essentially impunity, not enforcing any form of ethics or ensuring the development of the countries they're getting labor and resources from isn't stagnant. Earth Rights International reported on how Nestle and Cargill were sued for using child slavery in West Africa and after 15 years of legal process finally decided the US-based corporations were not liable for these human rights violations.

In contrast to the US, China has the Belt and Road Initiative started in 2013 where the state itself will lend money to improve the infrastructure development of these countries (and some in the global north as well), and allow for fully free trade (no tariffs) from the particularly underdeveloped. It faced initial backlash, which China responded to by improving their reporting standards and transparency with the countries they've signed contracts with, as described in China’s response to Belt and Road backlash. The initiative has continued to expand since then, and now has contracts with around 150 countries as listed by the Green Finance & Development Center in Countries of the Belt and Road Initiative (BRI), and accounts for around 20 trillion USD of trade, as reported by China in 2023 in a document called Vision and Actions for High-Quality Belt and Road Cooperation: Brighter Prospects for the Next Decade (cited via an English summary). The BRI has remained controversial within the west, but sentiment seems negative overall. Since 2020 various western publications have labeled the program "debt-trap diplomacy". There are some genuine concerns - China's reluctance to forgive debt and a lack of oversight on how the lent funds are used top amongst them - but I believe they're being exaggerated due to western's biases towards capitalist interests and general sinophobia. I'd link a specific article but there are so many that I'll actually just recommend looking through the wikipedia article for the Belt and Road Initiative which includes various articles from a lot of sources both in favor of and in opposition to the initiative. It has literally hundreds of citations, one of the most well-cited articles I've seen. I get the overall impression that the BRI is arguably more cooperative than exploitative in nature compared to the US strategy, and the countries themselves seem to view the initiative favorably, considering 3/4 of all UN recognized countries are already part of the initiative, with very few choosing not to renew contracts.

Further Reading

Jason Hickel made a very digestible explanation over the importance of liberating Palestine in the fight against imperialism, which was clipped into Why a Liberated Palestine Threatens Global Capitalism.

- +
Skip to content

Imperialism

770 words, ~4 minute read. Planted +.


Referenced by:LeftismMy Political Beliefs

Imperialism refers to how, after all the survivable land in the world was claimed by various countries (as part of colonialism), a country - or empire - must spread its influence over new territory at cost of existing influences over that territory. Typically this has meant land being transferred, either militarily or diplomatically.

Imperialism and Capitalism

Lenin wrote an influential pamphlet over his interpretation of imperialism, called "Imperialism, the Highest Stage of Capitalism". He argued imperialism was inextricably linked with capitalism, and that the driving force of imperialism was corporations gaining control over natural resources to use for profit, and to improve their position relative to opposing powers. An imperialist war, such as the ones the US has fought in the Middle East, serve both the interests of US oil companies as well as the US itself for its position relative to other imperialist powers. This view has been supported by modern leftist scholars like Michael Parenti in his book Face of Imperialism: Responsibility-Taking in the Political World.

In effect, imperialism has been used to delay resolving the contradiction between the need to expand and the physical limits of the globe. This contradiction cannot be fully resolved under a capitalist system, which requires the need to expand infinitely. Therefore, fighting imperialism means fighting capitalism. Removing power from corporations and banks largely nullifies the reasons for imperialism and is the best path towards global peace.

US Imperialism

The size of the US empire is not obvious just by looking at a map of the world, due to its reliance on economic influence and soft power. The US also imperializes through its remaining colonies, proxy wars, and foreign military bases. Second thought has a good introductory video on how significant some of those influences are in How The US Took Over The World.

A lot of these conflicts abroad are done in the open, such as the conflicts part of the war on terror. In this case the government needs to justify to its citizens going to war, which you'll typically see happen regardless of who's in charge. This is a process called manufactured consent, as described by Herman and Chomsky in Manufacturing Consent: The Political Economy of the Mass Media, although it is not perfect and the US has a history of anti-war protest movements. The vietnam war was our first televised war and had anti war protests even escalate into riots. Today through social media the impact of war is more accessible than ever before, and the Israel-Palestine conflict has had one of the largest anti-war movements yet, although still not as large as Vietnam.

While there are several imperialist powers in the world, the US is a particularly influential one that I, as an American citizen, have the most personal interest in stopping. I believe if the US moved towards socialism the overall influence of capitalism in the world would diminish so thoroughly that it would only further decline into non-existence. This would affect not only the prosperity of the world but save many lives as well: Western imperialism has caused 50-55 million deaths since WW2 as claimed by Andre Vltchek in On western terror, and US-backed conflicts show no sign of stopping so long as capitalist interests remain.

Impact of Imperialism on the Development of the Global South

The global south refers to a collection of countries that are under-developed compared to the "global north", and have historically been victims of colonialism and imperialism. Today, the global south makes up 90% of global labor but only receives 21% of globally produced value, according to Jason Hickel et al in Unequal exchange of labour in the world economy. Jason has previously calculated that the global north extracted $242 trillion in value from the global south between 1990 and 2015 alone, despite only returning 1/30th of that in the form of foreign aid, in Imperialist appropriation in the world economy: Drain from the global South through unequal exchange, 1990–2015.

It's worth noting that Hickel is discussing all of the global north, not just the US, but US corporations make heavy use of exploitation by underpaying workers without any form of representation for the exploited or assistance in modernizing these countries ("catching up" developmentally). They allow corporations to act with essentially impunity, not enforcing any form of ethics or ensuring the development of the countries they're getting labor and resources from isn't stagnant. Earth Rights International reported on how Nestle and Cargill were sued for using child slavery in West Africa and after 15 years of legal process finally decided the US-based corporations were not liable for these human rights violations.

In contrast to the US, China has the Belt and Road Initiative started in 2013 where the state itself will lend money to improve the infrastructure development of these countries (and some in the global north as well), and allow for fully free trade (no tariffs) from the particularly underdeveloped. It faced initial backlash, which China responded to by improving their reporting standards and transparency with the countries they've signed contracts with, as described in China’s response to Belt and Road backlash. The initiative has continued to expand since then, and now has contracts with around 150 countries as listed by the Green Finance & Development Center in Countries of the Belt and Road Initiative (BRI), and accounts for around 20 trillion USD of trade, as reported by China in 2023 in a document called Vision and Actions for High-Quality Belt and Road Cooperation: Brighter Prospects for the Next Decade (cited via an English summary). The BRI has remained controversial within the west, but sentiment seems negative overall. Since 2020 various western publications have labeled the program "debt-trap diplomacy". There are some genuine concerns - China's reluctance to forgive debt and a lack of oversight on how the lent funds are used top amongst them - but I believe they're being exaggerated due to western's biases towards capitalist interests and general sinophobia. I'd link a specific article but there are so many that I'll actually just recommend looking through the wikipedia article for the Belt and Road Initiative which includes various articles from a lot of sources both in favor of and in opposition to the initiative. It has literally hundreds of citations, one of the most well-cited articles I've seen. I get the overall impression that the BRI is arguably more cooperative than exploitative in nature compared to the US strategy, and the countries themselves seem to view the initiative favorably, considering 3/4 of all UN recognized countries are already part of the initiative, with very few choosing not to renew contracts.

Further Reading

Jason Hickel made a very digestible explanation over the importance of liberating Palestine in the fight against imperialism, which was clipped into Why a Liberated Palestine Threatens Global Capitalism.

+ \ No newline at end of file diff --git a/garden/incremental-social/index.html b/garden/incremental-social/index.html index 3fcad51cf..dc736c9a5 100644 --- a/garden/incremental-social/index.html +++ b/garden/incremental-social/index.html @@ -6,14 +6,14 @@ Incremental Social | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content
+ \ No newline at end of file diff --git a/garden/individualism/index.html b/garden/individualism/index.html index c57a8c3ac..7b831f86a 100644 --- a/garden/individualism/index.html +++ b/garden/individualism/index.html @@ -6,14 +6,14 @@ Individualism | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Individualism

195 words, ~1 minute read. Planted +

Skip to content

Individualism

195 words, ~1 minute read. Planted . Last tended to -.


Referenced by:AnarchismLocal CommunitiesNeoliberalism

Individualism is a Neoliberal value system centered around independence and self sufficiency. It argues for taking care of oneself before others, and that it's wrong for people to be forced to take care of others before their selves, i.e. via wealth redistribution. This value system is antithetical to the Anarchist values of community and mutual aid. I personally am against individualism and see it as against humans nature of cooperation. We're a social people and have for our entire existence relied upon each other.

As a personal anecdote, I'm a recent parent and the whole "it takes a village" adage makes a lot of sense, and has made me hyper aware of how individualism has made it very hard to raise a kid these days. There's no 3 generations living in a house anymore, and suburbs are spread out and isolating, preventing strong Local Communities from forming. To sum up, the "village" doesn't exist anymore.

Hyper individualism is a modern invention, not a "good ole traditional value" we should all aspire to. It was explicitly created by capitalist values, and replaced pre-existing value systems that prioritized co-operation.

- +.


Referenced by:AnarchismLocal CommunitiesNeoliberalism

Individualism is a Neoliberal value system centered around independence and self sufficiency. It argues for taking care of oneself before others, and that it's wrong for people to be forced to take care of others before their selves, i.e. via wealth redistribution. This value system is antithetical to the Anarchist values of community and mutual aid. I personally am against individualism and see it as against humans nature of cooperation. We're a social people and have for our entire existence relied upon each other.

As a personal anecdote, I'm a recent parent and the whole "it takes a village" adage makes a lot of sense, and has made me hyper aware of how individualism has made it very hard to raise a kid these days. There's no 3 generations living in a house anymore, and suburbs are spread out and isolating, preventing strong Local Communities from forming. To sum up, the "village" doesn't exist anymore.

Hyper individualism is a modern invention, not a "good ole traditional value" we should all aspire to. It was explicitly created by capitalist values, and replaced pre-existing value systems that prioritized co-operation.

+ \ No newline at end of file diff --git a/garden/ivy-road/index.html b/garden/ivy-road/index.html index 96f1d8426..9653a6119 100644 --- a/garden/ivy-road/index.html +++ b/garden/ivy-road/index.html @@ -6,14 +6,14 @@ Ivy Road | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Ivy Road

6 words, ~0 minute read. Planted +

Skip to content

Ivy Road

6 words, ~0 minute read. Planted . Last tended to -.


Referenced by:Davey WredenWanderstop
Tags:Davey Wreden

Ivy Road is a indie game studio created by Davey Wreden, Karla Kimonja, and C418

- +.


Referenced by:Davey WredenWanderstop
Tags:Davey Wreden

Ivy Road is a indie game studio created by Davey Wreden, Karla Kimonja, and C418

+ \ No newline at end of file diff --git a/garden/kronos/index.html b/garden/kronos/index.html index d10b0da81..0719069d5 100644 --- a/garden/kronos/index.html +++ b/garden/kronos/index.html @@ -6,14 +6,14 @@ Kronos | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Kronos

60 words, ~0 minute read. Planted +

Skip to content

Kronos

60 words, ~0 minute read. Planted . Last tended to -.


Referenced by:/nowV-ecs
Tags:My ProjectsProfectus

My largest and most ambitious incremental game I've ever made

  • A magnum opus, of sorts ;P

Still in development, and will be for a long time. I have full intention of completing it, however

An older version, that is built in The Modding Tree, only has the gameplay, and only goes up to Chapter 2, can be played here

- +.


Referenced by:/nowV-ecs
Tags:My ProjectsProfectus

My largest and most ambitious incremental game I've ever made

  • A magnum opus, of sorts ;P

Still in development, and will be for a long time. I have full intention of completing it, however

An older version, that is built in The Modding Tree, only has the gameplay, and only goes up to Chapter 2, can be played here

+ \ No newline at end of file diff --git a/garden/leftism/index.html b/garden/leftism/index.html index ba7322435..0153848aa 100644 --- a/garden/leftism/index.html +++ b/garden/leftism/index.html @@ -6,14 +6,14 @@ Leftism | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Leftism

1794 words, ~10 minute read. Planted +

Skip to content

Leftism

1794 words, ~10 minute read. Planted . Last tended to -.


Referenced by:DebateFilter BubblesMy Political BeliefsMy Political Journey

My Political Journey has brought me to the broad label of being a leftist. Leftism encompasses many ideologies, each with unique visions for an egalitarian society and strategies to achieve it. These pages are my tool to test my understanding by articulating these ideas in my own terms. I don't care to label myself any further than leftist, as in my mind I'm still a student of leftist ideologies and have personally been finding insight across the spectrum of leftist ideologies. As a reminder, this digital garden is a perpetual work in progress and only reflects my understanding of a topic at time of writing.

What is Leftism?

Leftism refers to a wide range of political ideologies that share a general opposition to hierarchical structures, particularly class hierarchies. Leftists seek an egalitarian society, though their vision of what this entails and how to achieve it vary significantly. They aim to replace systems based on profit and exploitation with ones prioritizing collective well-being. This typically places them against capitalism, however some leftists seek to retain the role of markets and sometimes even private property.

Major Leftist Ideologies

Marxism-Leninism

Marxist-Leninists believe the way towards communism - a classless, stateless, moneyless society - requires a transitionary phase called the "dictatorship of the proletariat". This involves a revolutionary vanguard party seizing control of the state to protect against counter-revolutionary forces and reorganize society along socialist lines. The vanguard party will typically do so by taking advantage of a crisis brought on by the contradictions of capitalism. As material abundance is achieved and exploitation becomes structurally impossible, the state will "wither away," giving rise to communism.

Examples of MLism include the Soviet Union and other 20th century communist movements.

Critiques of MLism focus on the authoritarian nature of the transitionary phase and whether the state will truly willingly "wither away" as described.

Maoism and Dengism are adaptations of MLism that apply it to the specific context of China following its Communist Revolution.

Anarchism

Anarchists reject the state entirely, viewing it as an inherently oppressive institution that cannot be reformed or repurposed for liberation. Anarchism envisions the immediate transition to a classless, stateless, moneyless society organized through voluntary associations, mutual aid, and decentralized decision-making. Unlike Marxist-Leninists, anarchists argue against any transitionary state, believing it will perpetuate hierarchy rather than dismantle it.

Historical examples include the anarchist collectives in Catalonia during the Spanish Civil War, which experimented with decentralized governance and worker control.

Critics of anarchism often point to decentralized systems being harder to "scale up" without introducing oppressive hierarchies, and their vulnerability to coordinated external threats.

The page dedicated to anarchism will philosophically explore what a stateless society looks like, but does not really cover the process of transitioning from capitalism to anarchism, as I have little confidence such a process is truly possible without a state to protect it, so long as capitalists and other reactionary powers exist.

Market Socialisms and Reformism

In contrast to anarchism and communism, these ideologies see markets as a tool for innovation and resource allocation, and argue for transitioning an existing state towards socialism without a vanguard party or revolution.

Syndicalism advocates for decentralized worker control through labor unions that would, through strikes and occupations, control the economy.

Social democracy and democratic socialism focus on reforming capitalist from the existing democratic processes, with the goal of reducing inequality and expanding social welfare. Bernie Sanders is a famous democratic socialist politician in America.

Anarchism vs Communism

Anarchism and communism are interesting in that they both describe a classless, stateless, and moneyless society. A society free from class antagonisms and the coercive apparatus of the state. They're both materialist schools of thought that both aim for the collective liberation of all and the abolition of hierarchical power structures. Yet famously these two groups have been at odds throughout history, such as after the Russian Revolution. They have a fundamental disagreement on how to arrive at their ideal society, and those differences are very interesting to explore. These differences not only feed into conflicts between the two groups, but undoubtedly yet subtly shape the society they're ostensibly both striving for.

Communism Strategy

Communists argue for a transitionary state - the "dictatorship of the proletariat" - as necessary for defending the revolution from both internal and external counter-revolutionary forces, as well as reorganizing the economy along socialist and eventually communism lines. This is a very long process, as they ultimately believe they need to abolish the material basis for class society, perhaps on a global scale due to Imperialism , before the process is complete. Nevertheless, the state is still seen as a temporary mechanism that will eventually become obsolete and naturally "wither away", as described by Lenin in State and Revolution:

And so in capitalist society we have a democracy that is curtailed, wretched, false, a democracy only for the rich, for the minority. The dictatorship of the proletariat, the period of transition to communism, will for the first time create democracy for the people, for the majority, along with the necessary suppression of the exploiters, of the minority. Communism alone is capable of providing really complete democracy, and the more complete it is, the sooner it will become unnecessary and wither away of its own accord.

In the same document, Lenin describes a talk by Engels to anarchists where he exasperatedly points out they share a common vision for ideal society, and they just disagree on the justifications for a transitionary state. Engels believed not installing the transitionary state would mean not being able to "crush the resistance of the bourgeoisie". That the immediate abolition of the state is impractical in the face of the immense power of capitalist and other reactionary forces.

Anarchist Strategy

Anarchists, on the other hand, refute the concept of a transitionary state as a necessary construct; they see installing a state of any kind as a reactionary obstacle to achieving their ideal society. Anarchists see the state as an inherently oppressive institution that cannot be reformed nor repurposed for liberation. As put by Kropotkin in The State: Its Historic Role:

There are those, on the one hand, who hope to achieve the social revolution through the State by preserving and even extending most of its powers to be used for the revolution. And there are those like ourselves who see the State, both in its present form, in its very essence, and in whatever guise it might appear, an obstacle to the social revolution, the greatest hindrance to the birth of a society based on equality and liberty, as well as the historic means designed to prevent this blossoming. The latter work to abolish the State and not to reform it.

They argue that regardless of intent, states are structurally designed to centralize power and perpetuate hierarchy. They believe a state will intrinsically lead to a new ruling class and undermining the revolutionary aims of equality and freedom. And most importantly, they do not accept that a state could "wither away of its own accord", but rather would forever justify its continued existence. As Bakunin put in Statism and Anarchy:

The differences between revolutionary dictatorship and statism are superficial. Fundamentally they both represent the same principle of minority rule over the majority in the name of the alleged “stupidity” of the latter and the alleged “intelligence” of the former. Therefore they are both equally reactionary since both directly and inevitably must preserve and perpetuate the political and economic privileges of the ruling minority and the political and economic subjugation of the masses of the people.

It should be noted that Marx responded to this text, reaffirming that the state would go away due to resource distribution becoming apolitical once abundance is achieved.

Naturally, anarchists also do not believe the economic role of the transitionary state is necessary either, but that a society, even pre-revolution, can work towards meeting the needs of everyone at the local community level through mutual aid and a focus on sustainable living.

Differences in their Visions

Due to the different paths to get there, the society each group strives for will be distinct in important ways, despite sharing the common characteristics of being classless, stateless, and moneyless. Communists arrived here almost incidentally after eradicating the material conditions for exploitation. They'll have reached an economic state of abundance, post-scarcity. Although Lenin makes it clear he still believes individuals can consume in excess and must be stopped, although he does not see the state as necessary for that effort:

We are not utopians, and do not in the least deny the possibility and inevitability of excesses on the part of individual persons, or the need to stop such excesses. In the first place, however, no special machine, no special apparatus of suppression, is needed for this: this will be done by the armed people themselves, as simply and as readily as any crowd of civilized people, even in modern society, interferes to put a stop to a scuffle or to prevent a woman from being assaulted. And, secondly, we know that the fundamental social cause of excesses, which consist in the violation of the rules of social intercourse, is the exploitation of the people, their want and their poverty. With the removal of this chief cause, excesses will inevitably begin to "wither away".

The take away here is that the communist vision may happen to be stateless and even follow some anarchist principles, but it was not designed to rigorously uphold all anarchist values. Of particular note, the advanced productive powers developed by the transitionary state would likely be a fairly centralized construct, even without a formal state, which anarchists would see as a coercive force that goes against the principle of free association. Anarchists, instead, would keep the economy decentralized, managing production on the local level guided by the principles of mutual aid and sustainability.

Leftist Infighting

Leftist infighting has long been a meme. While their disagreements are inevitable and valid, their intensity is often exacerbated by external forces seeking to dismantle leftist movements. The lack of a unifying framework is what makes leftism in particular susceptible to infighting.

The status quo creates an aligning force for similar ideologies, and makes any ideologies far away from the status quo feel comparatively dissimilar.

Marxist-Leninists advocate for a concept called democratic centralism to combat infighting. It mandates unity of action while allowing for internal debate and discussion. It's particularly useful and relevant for a vanguard party to ensure it is clear who has taken power following a revolution, rather than creating a power vacuum that can be exploited by imperialist powers. However, critics argue democratic centralism can stifle dissent and foster authoritarianism.

Moving Forward

As I describe in A Plea to Organize, despite differences between the different ideologies, my advice is still the same: Organize! Join local communities, regardless of affiliation, and support leftism and the community. Mutual aid efforts are particularly helpful and can be found on Mutual Aid Hub.

Additionally: Study! Read theory and better understand leftist ideologies of all stripes. It helps you better understand the philosophies underpinning these ideologies and in turn become a better leftist.

- +.


Referenced by:DebateFilter BubblesMy Political BeliefsMy Political Journey

My Political Journey has brought me to the broad label of being a leftist. Leftism encompasses many ideologies, each with unique visions for an egalitarian society and strategies to achieve it. These pages are my tool to test my understanding by articulating these ideas in my own terms. I don't care to label myself any further than leftist, as in my mind I'm still a student of leftist ideologies and have personally been finding insight across the spectrum of leftist ideologies. As a reminder, this digital garden is a perpetual work in progress and only reflects my understanding of a topic at time of writing.

What is Leftism?

Leftism refers to a wide range of political ideologies that share a general opposition to hierarchical structures, particularly class hierarchies. Leftists seek an egalitarian society, though their vision of what this entails and how to achieve it vary significantly. They aim to replace systems based on profit and exploitation with ones prioritizing collective well-being. This typically places them against capitalism, however some leftists seek to retain the role of markets and sometimes even private property.

Major Leftist Ideologies

Marxism-Leninism

Marxist-Leninists believe the way towards communism - a classless, stateless, moneyless society - requires a transitionary phase called the "dictatorship of the proletariat". This involves a revolutionary vanguard party seizing control of the state to protect against counter-revolutionary forces and reorganize society along socialist lines. The vanguard party will typically do so by taking advantage of a crisis brought on by the contradictions of capitalism. As material abundance is achieved and exploitation becomes structurally impossible, the state will "wither away," giving rise to communism.

Examples of MLism include the Soviet Union and other 20th century communist movements.

Critiques of MLism focus on the authoritarian nature of the transitionary phase and whether the state will truly willingly "wither away" as described.

Maoism and Dengism are adaptations of MLism that apply it to the specific context of China following its Communist Revolution.

Anarchism

Anarchists reject the state entirely, viewing it as an inherently oppressive institution that cannot be reformed or repurposed for liberation. Anarchism envisions the immediate transition to a classless, stateless, moneyless society organized through voluntary associations, mutual aid, and decentralized decision-making. Unlike Marxist-Leninists, anarchists argue against any transitionary state, believing it will perpetuate hierarchy rather than dismantle it.

Historical examples include the anarchist collectives in Catalonia during the Spanish Civil War, which experimented with decentralized governance and worker control.

Critics of anarchism often point to decentralized systems being harder to "scale up" without introducing oppressive hierarchies, and their vulnerability to coordinated external threats.

The page dedicated to anarchism will philosophically explore what a stateless society looks like, but does not really cover the process of transitioning from capitalism to anarchism, as I have little confidence such a process is truly possible without a state to protect it, so long as capitalists and other reactionary powers exist.

Market Socialisms and Reformism

In contrast to anarchism and communism, these ideologies see markets as a tool for innovation and resource allocation, and argue for transitioning an existing state towards socialism without a vanguard party or revolution.

Syndicalism advocates for decentralized worker control through labor unions that would, through strikes and occupations, control the economy.

Social democracy and democratic socialism focus on reforming capitalist from the existing democratic processes, with the goal of reducing inequality and expanding social welfare. Bernie Sanders is a famous democratic socialist politician in America.

Anarchism vs Communism

Anarchism and communism are interesting in that they both describe a classless, stateless, and moneyless society. A society free from class antagonisms and the coercive apparatus of the state. They're both materialist schools of thought that both aim for the collective liberation of all and the abolition of hierarchical power structures. Yet famously these two groups have been at odds throughout history, such as after the Russian Revolution. They have a fundamental disagreement on how to arrive at their ideal society, and those differences are very interesting to explore. These differences not only feed into conflicts between the two groups, but undoubtedly yet subtly shape the society they're ostensibly both striving for.

Communism Strategy

Communists argue for a transitionary state - the "dictatorship of the proletariat" - as necessary for defending the revolution from both internal and external counter-revolutionary forces, as well as reorganizing the economy along socialist and eventually communism lines. This is a very long process, as they ultimately believe they need to abolish the material basis for class society, perhaps on a global scale due to Imperialism , before the process is complete. Nevertheless, the state is still seen as a temporary mechanism that will eventually become obsolete and naturally "wither away", as described by Lenin in State and Revolution:

And so in capitalist society we have a democracy that is curtailed, wretched, false, a democracy only for the rich, for the minority. The dictatorship of the proletariat, the period of transition to communism, will for the first time create democracy for the people, for the majority, along with the necessary suppression of the exploiters, of the minority. Communism alone is capable of providing really complete democracy, and the more complete it is, the sooner it will become unnecessary and wither away of its own accord.

In the same document, Lenin describes a talk by Engels to anarchists where he exasperatedly points out they share a common vision for ideal society, and they just disagree on the justifications for a transitionary state. Engels believed not installing the transitionary state would mean not being able to "crush the resistance of the bourgeoisie". That the immediate abolition of the state is impractical in the face of the immense power of capitalist and other reactionary forces.

Anarchist Strategy

Anarchists, on the other hand, refute the concept of a transitionary state as a necessary construct; they see installing a state of any kind as a reactionary obstacle to achieving their ideal society. Anarchists see the state as an inherently oppressive institution that cannot be reformed nor repurposed for liberation. As put by Kropotkin in The State: Its Historic Role:

There are those, on the one hand, who hope to achieve the social revolution through the State by preserving and even extending most of its powers to be used for the revolution. And there are those like ourselves who see the State, both in its present form, in its very essence, and in whatever guise it might appear, an obstacle to the social revolution, the greatest hindrance to the birth of a society based on equality and liberty, as well as the historic means designed to prevent this blossoming. The latter work to abolish the State and not to reform it.

They argue that regardless of intent, states are structurally designed to centralize power and perpetuate hierarchy. They believe a state will intrinsically lead to a new ruling class and undermining the revolutionary aims of equality and freedom. And most importantly, they do not accept that a state could "wither away of its own accord", but rather would forever justify its continued existence. As Bakunin put in Statism and Anarchy:

The differences between revolutionary dictatorship and statism are superficial. Fundamentally they both represent the same principle of minority rule over the majority in the name of the alleged “stupidity” of the latter and the alleged “intelligence” of the former. Therefore they are both equally reactionary since both directly and inevitably must preserve and perpetuate the political and economic privileges of the ruling minority and the political and economic subjugation of the masses of the people.

It should be noted that Marx responded to this text, reaffirming that the state would go away due to resource distribution becoming apolitical once abundance is achieved.

Naturally, anarchists also do not believe the economic role of the transitionary state is necessary either, but that a society, even pre-revolution, can work towards meeting the needs of everyone at the local community level through mutual aid and a focus on sustainable living.

Differences in their Visions

Due to the different paths to get there, the society each group strives for will be distinct in important ways, despite sharing the common characteristics of being classless, stateless, and moneyless. Communists arrived here almost incidentally after eradicating the material conditions for exploitation. They'll have reached an economic state of abundance, post-scarcity. Although Lenin makes it clear he still believes individuals can consume in excess and must be stopped, although he does not see the state as necessary for that effort:

We are not utopians, and do not in the least deny the possibility and inevitability of excesses on the part of individual persons, or the need to stop such excesses. In the first place, however, no special machine, no special apparatus of suppression, is needed for this: this will be done by the armed people themselves, as simply and as readily as any crowd of civilized people, even in modern society, interferes to put a stop to a scuffle or to prevent a woman from being assaulted. And, secondly, we know that the fundamental social cause of excesses, which consist in the violation of the rules of social intercourse, is the exploitation of the people, their want and their poverty. With the removal of this chief cause, excesses will inevitably begin to "wither away".

The take away here is that the communist vision may happen to be stateless and even follow some anarchist principles, but it was not designed to rigorously uphold all anarchist values. Of particular note, the advanced productive powers developed by the transitionary state would likely be a fairly centralized construct, even without a formal state, which anarchists would see as a coercive force that goes against the principle of free association. Anarchists, instead, would keep the economy decentralized, managing production on the local level guided by the principles of mutual aid and sustainability.

Leftist Infighting

Leftist infighting has long been a meme. While their disagreements are inevitable and valid, their intensity is often exacerbated by external forces seeking to dismantle leftist movements. The lack of a unifying framework is what makes leftism in particular susceptible to infighting.

The status quo creates an aligning force for similar ideologies, and makes any ideologies far away from the status quo feel comparatively dissimilar.

Marxist-Leninists advocate for a concept called democratic centralism to combat infighting. It mandates unity of action while allowing for internal debate and discussion. It's particularly useful and relevant for a vanguard party to ensure it is clear who has taken power following a revolution, rather than creating a power vacuum that can be exploited by imperialist powers. However, critics argue democratic centralism can stifle dissent and foster authoritarianism.

Moving Forward

As I describe in A Plea to Organize, despite differences between the different ideologies, my advice is still the same: Organize! Join local communities, regardless of affiliation, and support leftism and the community. Mutual aid efforts are particularly helpful and can be found on Mutual Aid Hub.

Additionally: Study! Read theory and better understand leftist ideologies of all stripes. It helps you better understand the philosophies underpinning these ideologies and in turn become a better leftist.

+ \ No newline at end of file diff --git a/garden/life-is-strange/index.html b/garden/life-is-strange/index.html index 8496d2419..13db9d8fb 100644 --- a/garden/life-is-strange/index.html +++ b/garden/life-is-strange/index.html @@ -6,14 +6,14 @@ Life is Strange | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Life is Strange

654 words, ~4 minute read. Planted +

Skip to content

Life is Strange

654 words, ~4 minute read. Planted . Last tended to -.


A series of narrative driven video games with a focus on player choices

I really enjoyed the first game and engaged with the community a lot. I would get very emotional playing through the later chapters, and it became one of my favorite games.

Playthroughs I enjoyed:

Around the start of Haley and I's relationship, we'd play through LiS1 on projectors in our's classrooms

The ending

I was not a huge fan of the ending of Life is Strange. Of the two endings, one very clearly got a lot more resources spent on it, but I think Max's story has a better conclusion under the other.

In my mind, Max's arc (and major themes of the last chapter) was about learning not to rely on her powers, and to learn to live with the consequences of her actions. To that end, having the game end with her taking responsibility and living with the consequences of such a major event is a fitting thematic conclusion to the game and her character arc. In contrast, the other ending shows Max relying on her powers once again and, in my opinion, portrays Max as having not grown nor learned any lessons throughout the entire series. I think its a disservice this ending got so much more attention, with unique outfits and a song dedicated to it.

Life is Strange: Before the Storm

I really enjoyed this story. I didn't get quite as invested, perhaps due to it being a condensed 3 chapters rather than 5, but the characters will still just as amazing, which is what makes LiS so good. The ending didn't have as much of a punch as LiS1 - in fact, the entire back half of episode 3 didn't quite meet the bar in my eyes. At the time, I enjoyed these threads discussing criticisms levied at that part of the game:

Deadbones played through the game here

The Awesome Adventures of Captain Spirit

I enjoyed the demo, and it certainly got me hyped for LiS2 (although I would've been regardless). Switching to UE seemed like a really good move, and the comic theme fits the aesthetic of the series well.

Life is Strange 2

Unfortunately, I've only played the first chapter of this game. I wanted to play through it with Haley, but we haven't found time to do so.

LATER Skip the rest of LiS1 and play LiS2 with Haley

Life is Strange: True Colors

This game seems interesting, although the power does seem a little funnily close to "has empathy". I haven't had time to play it, but would like to.

Life is Strange: Double Exposure

I'm very excited for this game! Returning to Max's story sounds awesome. Although I will say, from the trailer alone it's incredibly obvious what one of the story beats will be: Revealing that the two timelines follow the two disparate endings from LiS1.

This game was announced to come with premium editions that get access to the game earlier

  • I think this is a horrible anti-consumer practice
  • Since this game is narratively driven, it is prone to spoilers
  • They're getting more money from their biggest fans without providing any tangible value to them, other than making the experience worse for everyone who plays but doesn't cough up that money
  • I hope other narratively driven games find other ways to do Video Game Monetization
- +.


A series of narrative driven video games with a focus on player choices

I really enjoyed the first game and engaged with the community a lot. I would get very emotional playing through the later chapters, and it became one of my favorite games.

Playthroughs I enjoyed:

Around the start of Haley and I's relationship, we'd play through LiS1 on projectors in our's classrooms

The ending

I was not a huge fan of the ending of Life is Strange. Of the two endings, one very clearly got a lot more resources spent on it, but I think Max's story has a better conclusion under the other.

In my mind, Max's arc (and major themes of the last chapter) was about learning not to rely on her powers, and to learn to live with the consequences of her actions. To that end, having the game end with her taking responsibility and living with the consequences of such a major event is a fitting thematic conclusion to the game and her character arc. In contrast, the other ending shows Max relying on her powers once again and, in my opinion, portrays Max as having not grown nor learned any lessons throughout the entire series. I think its a disservice this ending got so much more attention, with unique outfits and a song dedicated to it.

Life is Strange: Before the Storm

I really enjoyed this story. I didn't get quite as invested, perhaps due to it being a condensed 3 chapters rather than 5, but the characters will still just as amazing, which is what makes LiS so good. The ending didn't have as much of a punch as LiS1 - in fact, the entire back half of episode 3 didn't quite meet the bar in my eyes. At the time, I enjoyed these threads discussing criticisms levied at that part of the game:

Deadbones played through the game here

The Awesome Adventures of Captain Spirit

I enjoyed the demo, and it certainly got me hyped for LiS2 (although I would've been regardless). Switching to UE seemed like a really good move, and the comic theme fits the aesthetic of the series well.

Life is Strange 2

Unfortunately, I've only played the first chapter of this game. I wanted to play through it with Haley, but we haven't found time to do so.

LATER Skip the rest of LiS1 and play LiS2 with Haley

Life is Strange: True Colors

This game seems interesting, although the power does seem a little funnily close to "has empathy". I haven't had time to play it, but would like to.

Life is Strange: Double Exposure

I'm very excited for this game! Returning to Max's story sounds awesome. Although I will say, from the trailer alone it's incredibly obvious what one of the story beats will be: Revealing that the two timelines follow the two disparate endings from LiS1.

This game was announced to come with premium editions that get access to the game earlier

  • I think this is a horrible anti-consumer practice
  • Since this game is narratively driven, it is prone to spoilers
  • They're getting more money from their biggest fans without providing any tangible value to them, other than making the experience worse for everyone who plays but doesn't cough up that money
  • I hope other narratively driven games find other ways to do Video Game Monetization
+ \ No newline at end of file diff --git a/garden/local-communities/index.html b/garden/local-communities/index.html index 8e47ca4f2..c36f009d7 100644 --- a/garden/local-communities/index.html +++ b/garden/local-communities/index.html @@ -6,14 +6,14 @@ Local Communities | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Local Communities

302 words, ~2 minute read. Planted +

Skip to content

Local Communities

302 words, ~2 minute read. Planted . Last tended to -.


Referenced by:AnarchismDigital LocalityIndividualism

Strongly connected local communities are important to have. They satisfy our social needs for in-person connections, and help organize mutual aid. These needs cannot be sufficiently satisfied exclusively by online friends/communities - of particular note, new parents need help raising their kid.

Historically, society has had these strongly connected local communities, via the way society was organized (i.e. tribes, multi-generational households, etc.) or through entities that focused on community (i.e. local churches). Churches in particular would ensure everyone meets up regularly to see each other, connect, and catch up. They'd host community events and services throughout the year, and mobilize the community during emergencies.

The religious aspect of churches was never a requirement for the benefits they contributed to their local communities, and in fact there are mega-churches today that do not confer these benefits despite retaining the religious aspect.

There are several reasons for why local communities have since weakened. The car has weakened them by making the people physically more spread out and reducing the number of "third places". The internet created a convenient alternative whose communities were not immediately recognized as insufficient imitations of in person communities. Newer generations trend towards irreligiousness, making churches decreasingly popular. Combined, these changes have led to a cultural shift towards Individualism and Neoliberalism that has further cemented our weakened local communities.

The way to "fix" our local communities and make them more strongly connected is to support multi-generational households, increasing population density, and using or creating entities that can replace the community-building role of the church. Such alternatives could be community centers or HOAs. HOAs get a bad reputation due to their tendency to attract those who want power to micro-manage the community, but there are ways to organize them to mitigate that issue (see Anarchism).

- +.


Referenced by:AnarchismDigital LocalityIndividualism

Strongly connected local communities are important to have. They satisfy our social needs for in-person connections, and help organize mutual aid. These needs cannot be sufficiently satisfied exclusively by online friends/communities - of particular note, new parents need help raising their kid.

Historically, society has had these strongly connected local communities, via the way society was organized (i.e. tribes, multi-generational households, etc.) or through entities that focused on community (i.e. local churches). Churches in particular would ensure everyone meets up regularly to see each other, connect, and catch up. They'd host community events and services throughout the year, and mobilize the community during emergencies.

The religious aspect of churches was never a requirement for the benefits they contributed to their local communities, and in fact there are mega-churches today that do not confer these benefits despite retaining the religious aspect.

There are several reasons for why local communities have since weakened. The car has weakened them by making the people physically more spread out and reducing the number of "third places". The internet created a convenient alternative whose communities were not immediately recognized as insufficient imitations of in person communities. Newer generations trend towards irreligiousness, making churches decreasingly popular. Combined, these changes have led to a cultural shift towards Individualism and Neoliberalism that has further cemented our weakened local communities.

The way to "fix" our local communities and make them more strongly connected is to support multi-generational households, increasing population density, and using or creating entities that can replace the community-building role of the church. Such alternatives could be community centers or HOAs. HOAs get a bad reputation due to their tendency to attract those who want power to micro-manage the community, but there are ways to organize them to mitigate that issue (see Anarchism).

+ \ No newline at end of file diff --git a/garden/local-first-software/index.html b/garden/local-first-software/index.html index a59cb46a2..c8361891c 100644 --- a/garden/local-first-software/index.html +++ b/garden/local-first-software/index.html @@ -6,14 +6,14 @@ Local-First Software | The Paper Pilot - + - + - - - + + + @@ -53,9 +53,9 @@ -
Skip to content

Local-First Software

48 words, ~0 minute read. Planted -.


Referenced by:Orchard

Software that is designed to operate fully offline, that can sync when connected to other clients. This means giving users ownership over their data while still allowing for collaboration.

Find a bunch of resources explaining the concept, how to implement it, and some examples at https://localfirstweb.dev/

- +
Skip to content

Local-First Software

48 words, ~0 minute read. Planted +.


Referenced by:Orchard

Software that is designed to operate fully offline, that can sync when connected to other clients. This means giving users ownership over their data while still allowing for collaboration.

Find a bunch of resources explaining the concept, how to implement it, and some examples at https://localfirstweb.dev/

+ \ No newline at end of file diff --git a/garden/logseq/index.html b/garden/logseq/index.html index 52f17451e..e1afdfa55 100644 --- a/garden/logseq/index.html +++ b/garden/logseq/index.html @@ -6,14 +6,14 @@ Logseq | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Logseq

3 words, ~0 minute read. Planted +

Skip to content

Logseq

3 words, ~0 minute read. Planted . Last tended to -.


Referenced by:Command PalettesMy Personal WebsiteThis Knowledge Hub

Logseq is an Open Source outlining software

- +.


Referenced by:Command PalettesMy Personal WebsiteThis Knowledge Hub

Logseq is an Open Source outlining software

+ \ No newline at end of file diff --git a/garden/matrix/index.html b/garden/matrix/index.html index 206e4c623..5e849d976 100644 --- a/garden/matrix/index.html +++ b/garden/matrix/index.html @@ -6,14 +6,14 @@ Matrix | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Matrix

2 words, ~0 minute read. Planted +

Skip to content

Matrix

2 words, ~0 minute read. Planted . Last tended to -.


Referenced by:CinnyCommuneSynapse

Matrix is a protocol for Decentralized messaging

- +.


Referenced by:CinnyCommuneSynapse

Matrix is a protocol for Decentralized messaging

+ \ No newline at end of file diff --git a/garden/mbin/index.html b/garden/mbin/index.html index 856f0a0b4..03954e789 100644 --- a/garden/mbin/index.html +++ b/garden/mbin/index.html @@ -6,14 +6,14 @@ Mbin | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Mbin

12 words, ~0 minute read. Planted +

Skip to content

Mbin

12 words, ~0 minute read. Planted . Last tended to -.


Referenced by:Incremental Social

Mbin is an Open Source Fediverse software

Can show both twitter-style posts and reddit-style threads

- +.


Referenced by:Incremental Social

Mbin is an Open Source Fediverse software

Can show both twitter-style posts and reddit-style threads

+ \ No newline at end of file diff --git a/garden/moderation/index.html b/garden/moderation/index.html index ada3530e9..d0307a47d 100644 --- a/garden/moderation/index.html +++ b/garden/moderation/index.html @@ -6,14 +6,14 @@ Moderation | The Paper Pilot - + - + - - - + + + @@ -53,9 +53,9 @@ -
Skip to content

Moderation

365 words, ~2 minute read. Planted -.


Referenced by:Decentralized Moderation

Moderation, in the context of Social Media, is the enforcement of rules by removing offending content, and optionally punishing the offender through silencing, banning, or other measures.

What these rules are will typically vary platform to platform, and sometimes even community to community. This stems from different communities having different purposes or goals, along with differing views on what is acceptable speech. For example, a forums for victims of abuse may feature very heavy moderation, or a community for Christians may limit joining the community to only fellow Christians.

Free Speech

Some platforms try to be very light handed with their moderation, often arguing that infringing on speech is inherently censorship and must be avoided unless it's literally against the law to say. These people are called "Free Speech Absolutists". In practice, most of those advocating for free speech absolutism are just fine censoring speech they disagree with, such as Elon Musk. He has been biased towards his personal views and self interests both in deciding which government censorship requests X complies with and promoting his own posts above others.

In general, those arguing for less moderation or more free speech are doing so from a position of privilege. In traditional social media, those with more power have more speech (that is, they're more influential), so arguing for free speech is perpetuating the existing power dynamics by giving them lots of speech and removing the ability for more fringe groups to have that hateful content removed. The fringe may criticize, but that won't likely be enough to change anything, as their calls to deplatform those in the ruling class are stymied by arguments for free speech.

However, these concerns regarding free speech would likely be mostly mitigated by Decentralized Social Media and may lead to overall more lax rules in social media with Decentralized Moderation.

Blocklists

Blocklists are lists of users someone has blocked, that they then share with the public. Some blocklists even auto update as the creator adds new users to them.

Blocklists are a double edged sword. They can help, for example, marginalized communities block those who wish them harm regularly. However, they centralize power and are often abused. I recommend this article which discusses blocklists and how they help and how they harm, especially with respect to marginalized communities.

- +
Skip to content

Moderation

365 words, ~2 minute read. Planted +.


Referenced by:Decentralized Moderation

Moderation, in the context of Social Media, is the enforcement of rules by removing offending content, and optionally punishing the offender through silencing, banning, or other measures.

What these rules are will typically vary platform to platform, and sometimes even community to community. This stems from different communities having different purposes or goals, along with differing views on what is acceptable speech. For example, a forums for victims of abuse may feature very heavy moderation, or a community for Christians may limit joining the community to only fellow Christians.

Free Speech

Some platforms try to be very light handed with their moderation, often arguing that infringing on speech is inherently censorship and must be avoided unless it's literally against the law to say. These people are called "Free Speech Absolutists". In practice, most of those advocating for free speech absolutism are just fine censoring speech they disagree with, such as Elon Musk. He has been biased towards his personal views and self interests both in deciding which government censorship requests X complies with and promoting his own posts above others.

In general, those arguing for less moderation or more free speech are doing so from a position of privilege. In traditional social media, those with more power have more speech (that is, they're more influential), so arguing for free speech is perpetuating the existing power dynamics by giving them lots of speech and removing the ability for more fringe groups to have that hateful content removed. The fringe may criticize, but that won't likely be enough to change anything, as their calls to deplatform those in the ruling class are stymied by arguments for free speech.

However, these concerns regarding free speech would likely be mostly mitigated by Decentralized Social Media and may lead to overall more lax rules in social media with Decentralized Moderation.

Blocklists

Blocklists are lists of users someone has blocked, that they then share with the public. Some blocklists even auto update as the creator adds new users to them.

Blocklists are a double edged sword. They can help, for example, marginalized communities block those who wish them harm regularly. However, they centralize power and are often abused. I recommend this article which discusses blocklists and how they help and how they harm, especially with respect to marginalized communities.

+ \ No newline at end of file diff --git a/garden/mtx/index.html b/garden/mtx/index.html index 8d53e77b2..e932e8e8f 100644 --- a/garden/mtx/index.html +++ b/garden/mtx/index.html @@ -6,14 +6,14 @@ MTX | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

MTX

10 words, ~0 minute read. Planted +

Skip to content

MTX

10 words, ~0 minute read. Planted . Last tended to -.


Referenced by:Premium CurrencyVideo Game Monetization

Purchaseable items in video games that cost real life currencies

- +.


Referenced by:Premium CurrencyVideo Game Monetization

Purchaseable items in video games that cost real life currencies

+ \ No newline at end of file diff --git a/garden/my-browser-stack/index.html b/garden/my-browser-stack/index.html index 8263a0d50..31bb434e8 100644 --- a/garden/my-browser-stack/index.html +++ b/garden/my-browser-stack/index.html @@ -6,14 +6,14 @@ My Browser Stack | The Paper Pilot - + - + - - - + + + @@ -53,9 +53,9 @@ -
Skip to content

My Browser Stack

447 words, ~2 minute read. Planted -.


This is the list of tools I use for browsing the internet in a safe way that ensures it's a pleasant experience.

Browser

I've used a lot of browsers over time, and currently use Zen because of it's modern look. At this point I really just recommend any fork of Firefox (such as Zen). Mozilla has seen its fair share of controversy, but nowhere near the amount Google has, and it's worth using a Firefox based browser in order to fight the chrome monopoly.

Other great Firefox forks to look at are librewolf and waterfox, which are privacy centric and lightweight and run faster than stock firefox.

Extensions

A classic recommendation you've probably already heard, uBlock Origin is a requirement for browsing the internet. Ads spy on you and significantly degrade your browsing experience, and this extension fixes that. Gorhill, it's creator, deserves so much appreciation for the service they've done to the entire world.

Youtube

If you browse YouTube in your browser, you might be interested in these extensions as well:

Sponsorblock uses crowd sourced information on YouTube videos to automatically skip past parts you don't care about, like sponsor reads or calls to like or subscribe.

DeArrow uses crowd sourced information on YouTube videos to replace the original titles with more descriptive ones (to avoid click bait). It'll also replace thumbnails with random frames from the video itself. Note this extension asks for a $1 donation or to request free access, which can take a few hours (but you can "trial" the extension in the meantime).

With the advent of AI generated content, it has become much more difficult to search the web. Here's some techniques to find useful, original, human made resources.

If you'd like to clean up your mainstream search engine results(Google, DuckDuckGo, or Bing), you can use the Huge AI Blocklist. The list works with uBlock Origin, but they recommend using uBlacklist, an extension specifically for blocking certain Google search results.

If you're willing to pay, Kagi is a premium search engine you may be interested in. Being a paid service, it doesn't rely on ads or tracking to make a profit, and has a great reputation for high quality results and additional features free search engines don't have like personalized rankings for domains.

There is also an independent search engine called Marginalia that designed to show you non commercialized sites that are typically smaller and independent, which acts as a great filter to only see human made resources.

Finally, if your goal is just privacy, the extension mentioned in the following section will help redirect you to alternative search engines as well.

Privacy respecting front ends

There are many projects out there that offer sites you can go to that interface with popular but not privacy respecting websites like YouTube or Twitter. This is personally a bit overkill for me, but I've considered using them in the past. Rather than looking up each alternative directly and finding a working instance, I recommend just using a regularly maintained extension that automatically redirects you from the popular site to a working instance of the alternative frontend, like Privacy Redirect.

- +
Skip to content

My Browser Stack

447 words, ~2 minute read. Planted +.


This is the list of tools I use for browsing the internet in a safe way that ensures it's a pleasant experience.

Browser

I've used a lot of browsers over time, and currently use Zen because of it's modern look. At this point I really just recommend any fork of Firefox (such as Zen). Mozilla has seen its fair share of controversy, but nowhere near the amount Google has, and it's worth using a Firefox based browser in order to fight the chrome monopoly.

Other great Firefox forks to look at are librewolf and waterfox, which are privacy centric and lightweight and run faster than stock firefox.

Extensions

A classic recommendation you've probably already heard, uBlock Origin is a requirement for browsing the internet. Ads spy on you and significantly degrade your browsing experience, and this extension fixes that. Gorhill, it's creator, deserves so much appreciation for the service they've done to the entire world.

Youtube

If you browse YouTube in your browser, you might be interested in these extensions as well:

Sponsorblock uses crowd sourced information on YouTube videos to automatically skip past parts you don't care about, like sponsor reads or calls to like or subscribe.

DeArrow uses crowd sourced information on YouTube videos to replace the original titles with more descriptive ones (to avoid click bait). It'll also replace thumbnails with random frames from the video itself. Note this extension asks for a $1 donation or to request free access, which can take a few hours (but you can "trial" the extension in the meantime).

With the advent of AI generated content, it has become much more difficult to search the web. Here's some techniques to find useful, original, human made resources.

If you'd like to clean up your mainstream search engine results(Google, DuckDuckGo, or Bing), you can use the Huge AI Blocklist. The list works with uBlock Origin, but they recommend using uBlacklist, an extension specifically for blocking certain Google search results.

If you're willing to pay, Kagi is a premium search engine you may be interested in. Being a paid service, it doesn't rely on ads or tracking to make a profit, and has a great reputation for high quality results and additional features free search engines don't have like personalized rankings for domains.

There is also an independent search engine called Marginalia that designed to show you non commercialized sites that are typically smaller and independent, which acts as a great filter to only see human made resources.

Finally, if your goal is just privacy, the extension mentioned in the following section will help redirect you to alternative search engines as well.

Privacy respecting front ends

There are many projects out there that offer sites you can go to that interface with popular but not privacy respecting websites like YouTube or Twitter. This is personally a bit overkill for me, but I've considered using them in the past. Rather than looking up each alternative directly and finding a working instance, I recommend just using a regularly maintained extension that automatically redirects you from the popular site to a working instance of the alternative frontend, like Privacy Redirect.

+ \ No newline at end of file diff --git a/garden/my-personal-website/index.html b/garden/my-personal-website/index.html index 302ea2573..7dbc6e458 100644 --- a/garden/my-personal-website/index.html +++ b/garden/my-personal-website/index.html @@ -6,14 +6,14 @@ My Personal Website | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

My Personal Website

422 words, ~2 minute read. Planted +

Skip to content

My Personal Website

422 words, ~2 minute read. Planted . Last tended to -.


Referenced by:The Small WebThis Knowledge Hub

A Personal Websites for myself, available at https://thepaperpilot.org

Tech Stack

I use Logseq to journal and collect my thoughts on various topics that interest me

  • Seafile syncs my logseq files between my devices
  • Git syncs my logseq files to a private repo on Incremental Social for purposes of version control and using as a submodule
  • The seafile files and all repos on Incremental Social are independently backed up daily to backblaze

My logseq files are synced to a private git repo which is added as a submodule to my website repo

A Node.js script pre-processes my logseq files into markdown files in the /garden path of the website

  • Converts all links and block references
  • Adds lists of tags and references to pages
  • Adds <h1 /> titles, word counts, update commits, etc. to each page
  • Moves the /now page to /now instead of /garden/now
  • Copies some of the Guide to Incrementals pages to /guide-to-incrementals so as to not break links made before the current site iteration
  • Generates /changelog and its RSS, Atom, and JSON feeds
    • The outputs of the generation are NOT .gitignore'd, as I use the git log to determine which pages updated when - Commit information about when a file was last updated is added via a data loader because if it was added to the file directly, rebuilding the site would count as having updated every page, by updating each commit to the changes introduced last build

Vitepress builds a static site from the markdown files

  • Includes a custom theme that makes the whole site paper-themed
  • Includes some pages like the homepage and the about me page that require markup, thus don't make sense to maintain inside logseq
  • The sidebar is generated from my favorited pages within Logseq
  • Includes various static files, like copies of several of my games and a robots.txt (borrowed from Tracy Durnell's robots.txt) that blocks several crawlers specifically used for training AI models

Three.js is used to create the effect in the background

  • Simplex noise gets used to adjust the opacity of a repeating SVG pattern
  • Initially tried to use just SVG, which supports creating noise and using it as a mask, but it only does 2d noise and I need 2d slices of 3d noise

Microformats are used to markup the site for The IndieWeb

  • The footer contains a minimal h-card with a link to my full profile
  • Each garden page is an h-entry, and the changelog an h-feed
  • All my socials are added as rel-me links, and the profiles then link back to me (as rel-me links, if allowed by the platform)
    • Together this can verify the owner of this website and those socials are the same person
- +.


Referenced by:The Small WebThis Knowledge Hub

A Personal Websites for myself, available at https://thepaperpilot.org

Tech Stack

I use Logseq to journal and collect my thoughts on various topics that interest me

  • Seafile syncs my logseq files between my devices
  • Git syncs my logseq files to a private repo on Incremental Social for purposes of version control and using as a submodule
  • The seafile files and all repos on Incremental Social are independently backed up daily to backblaze

My logseq files are synced to a private git repo which is added as a submodule to my website repo

A Node.js script pre-processes my logseq files into markdown files in the /garden path of the website

  • Converts all links and block references
  • Adds lists of tags and references to pages
  • Adds <h1 /> titles, word counts, update commits, etc. to each page
  • Moves the /now page to /now instead of /garden/now
  • Copies some of the Guide to Incrementals pages to /guide-to-incrementals so as to not break links made before the current site iteration
  • Generates /changelog and its RSS, Atom, and JSON feeds
    • The outputs of the generation are NOT .gitignore'd, as I use the git log to determine which pages updated when - Commit information about when a file was last updated is added via a data loader because if it was added to the file directly, rebuilding the site would count as having updated every page, by updating each commit to the changes introduced last build

Vitepress builds a static site from the markdown files

  • Includes a custom theme that makes the whole site paper-themed
  • Includes some pages like the homepage and the about me page that require markup, thus don't make sense to maintain inside logseq
  • The sidebar is generated from my favorited pages within Logseq
  • Includes various static files, like copies of several of my games and a robots.txt (borrowed from Tracy Durnell's robots.txt) that blocks several crawlers specifically used for training AI models

Three.js is used to create the effect in the background

  • Simplex noise gets used to adjust the opacity of a repeating SVG pattern
  • Initially tried to use just SVG, which supports creating noise and using it as a mask, but it only does 2d noise and I need 2d slices of 3d noise

Microformats are used to markup the site for The IndieWeb

  • The footer contains a minimal h-card with a link to my full profile
  • Each garden page is an h-entry, and the changelog an h-feed
  • All my socials are added as rel-me links, and the profiles then link back to me (as rel-me links, if allowed by the platform)
    • Together this can verify the owner of this website and those socials are the same person
+ \ No newline at end of file diff --git a/garden/my-political-beliefs/index.html b/garden/my-political-beliefs/index.html index 9e759cfef..7afc12e62 100644 --- a/garden/my-political-beliefs/index.html +++ b/garden/my-political-beliefs/index.html @@ -6,14 +6,14 @@ My Political Beliefs | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

My Political Beliefs

213 words, ~1 minute read. Planted +

Skip to content

My Political Beliefs

213 words, ~1 minute read. Planted . Last tended to -.


Referenced by:My Political JourneyPolitical Quizzes

Government

I'm definitely a Leftist, and believe our end goal should be a classless, stateless, moneyless society, but acknowledge the role of the state in defending against, at the very least, Imperialist forces abroad, so long as they exist.

I want to eventually reach a society structured as decentralized local communities that operate through Consensus Democracy , and freely associate with other communities for larger scale organizing, such as building and maintaining a rail line.

Economy

I believe we should eventually arrive at communism; a post-scarcity society where everyone's needs are met via automation and without the need for currency. Along the way there I expect us to democratize the workplace and work towards nationalizing every idustry.

Society

I believe in maximizing personal liberties, so long as one is not actively harmful to others, including most forms of discrimination.

Security

I'm against the use of violence by anyone, including the state. I believe in Police Abolition and am against the military and espionage both foreign and domestic. I believe in the Anarchist value of free association, so I believe we should have fully open borders, both for travel and immigration/emigration. I am anti-imperialist and believe in a fairly isolationist foreign policy, but am not against humanitarian foreign aid.

- +.


Referenced by:My Political JourneyPolitical Quizzes

Government

I'm definitely a Leftist, and believe our end goal should be a classless, stateless, moneyless society, but acknowledge the role of the state in defending against, at the very least, Imperialist forces abroad, so long as they exist.

I want to eventually reach a society structured as decentralized local communities that operate through Consensus Democracy , and freely associate with other communities for larger scale organizing, such as building and maintaining a rail line.

Economy

I believe we should eventually arrive at communism; a post-scarcity society where everyone's needs are met via automation and without the need for currency. Along the way there I expect us to democratize the workplace and work towards nationalizing every idustry.

Society

I believe in maximizing personal liberties, so long as one is not actively harmful to others, including most forms of discrimination.

Security

I'm against the use of violence by anyone, including the state. I believe in Police Abolition and am against the military and espionage both foreign and domestic. I believe in the Anarchist value of free association, so I believe we should have fully open borders, both for travel and immigration/emigration. I am anti-imperialist and believe in a fairly isolationist foreign policy, but am not against humanitarian foreign aid.

+ \ No newline at end of file diff --git a/garden/my-political-journey/index.html b/garden/my-political-journey/index.html index 8b8f1380d..95087a41f 100644 --- a/garden/my-political-journey/index.html +++ b/garden/my-political-journey/index.html @@ -6,14 +6,14 @@ My Political Journey | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

My Political Journey

714 words, ~4 minute read. Planted +

Skip to content

My Political Journey

714 words, ~4 minute read. Planted . Last tended to -.


Referenced by:LeftismPolitical Quizzes

My Political Beliefs have changed over time, although I believe it mostly stems from me becoming increasingly informed. Since this website contains content from as far back as 2006, when I was only 10 years old, I'd like to make it extremely clear that I have changed as a person, as we all have, and disavow a lot of my older opinions, roughly everything before 2020 or so but to be safe let's just give a dynamic (current date - 2 years). It's likely you are on this page from viewing a timeline post from that range and clicking the banner. There are bits in that period I may still agree with, but perhaps it would be best to just assume I don't have a stance on it unless there's something more recent about it. Pages in the garden section of this site are evergreen though, meaning I'll keep them up to date as my views change. Feel completely free to judge me for my opinions in there.

Core beliefs

I believe I've been fairly political since I was quite young, and had a relatively consistent set of core values that have just been expressed in different ways and through different lenses during different points of my life. For example I've always believed in fairness, but have used that belief to both argue for and against affirmative action. Concepts like freedom or meritocracies have similarly been redefined as I've become more aware of the influence of imperialism and colonialism on our cultural values and society.

Other beliefs of mine have always been around, but I just wasn't informed enough to properly express my views. I've voiced for a very long time that I think society will inevitably trend towards post-scarcity, a world without class, currency, or jobs, where all our needs and desires are met fully, automatically, and sustainably. I've never once pictured that society retaining a hierarchy of wealth or power in any way. But I would not have recognized that as an anarchistic society until relatively recently, mostly due to misinformation and propaganda against anarchy.

Anti-SJW

Alright, I'm guessing you're specifically on this page because you saw me upvote something on r/KotakuInAction or like a video from PSASitch or something like that. I'm not proud of this time period, where I read and watched a bit of Anti-SJW content. I'm glad to have moved on from this point of my life, and wish it hadn't happened in the first place. I don't really have any excuses, but appreciate understanding that I have grown as a person since this time.

I migrated a LOT of posts to this website for the sake of having them all in one place and under my control, rather than other websites'. I have not been able to look through the tens of thousands of posts (mostly upvotes/likes), but have done some basic filtering of these opinions I no longer hold. I'm open about the fact I once held these beliefs, but I don't need to be de facto promoting them by sharing them on this website. If you stumble across a post you think I'd rather not have on this site anymore, please reach out.

Radicalization

I believe a lot of things contributed to my radicalization, which happened sometime in the early 2020s. Ultimately I think I was just aware that I didn't really like the views I was being exposed to, the direction that media was trying to to pull me, and slowly over time just engaged less and less with that kind of content. I'd always been very economically leftist, so just needed to get over my edgy/cringe phase. I think what put the nail in the coffin was watching through the alt right playbook, a great series I highly recommend. I also started really enjoying a lot of leftist creators, like hasanabi, philosophy tube, and others. The people around me also affect my views, and after leaving college I think I interacted with nicer people on average. Of particular note here is my wife, who had their own political journey which has similarly culminated in us sort of having a positive feedback loop further and further left. Certain events like the BLM protests following George Floyd similarly cemented our position further and further left.

I actually want to also point out I've found a lot of people in this space to be very accepting of people who previously held problematic beliefs. It's largely why I feel comfortable (enough) having a lot of my history public both on this page and the site in general, and being able to describe how my political journey got me to where I am today, a very radical Leftist.

- +.


Referenced by:LeftismPolitical Quizzes

My Political Beliefs have changed over time, although I believe it mostly stems from me becoming increasingly informed. Since this website contains content from as far back as 2006, when I was only 10 years old, I'd like to make it extremely clear that I have changed as a person, as we all have, and disavow a lot of my older opinions, roughly everything before 2020 or so but to be safe let's just give a dynamic (current date - 2 years). It's likely you are on this page from viewing a timeline post from that range and clicking the banner. There are bits in that period I may still agree with, but perhaps it would be best to just assume I don't have a stance on it unless there's something more recent about it. Pages in the garden section of this site are evergreen though, meaning I'll keep them up to date as my views change. Feel completely free to judge me for my opinions in there.

Core beliefs

I believe I've been fairly political since I was quite young, and had a relatively consistent set of core values that have just been expressed in different ways and through different lenses during different points of my life. For example I've always believed in fairness, but have used that belief to both argue for and against affirmative action. Concepts like freedom or meritocracies have similarly been redefined as I've become more aware of the influence of imperialism and colonialism on our cultural values and society.

Other beliefs of mine have always been around, but I just wasn't informed enough to properly express my views. I've voiced for a very long time that I think society will inevitably trend towards post-scarcity, a world without class, currency, or jobs, where all our needs and desires are met fully, automatically, and sustainably. I've never once pictured that society retaining a hierarchy of wealth or power in any way. But I would not have recognized that as an anarchistic society until relatively recently, mostly due to misinformation and propaganda against anarchy.

Anti-SJW

Alright, I'm guessing you're specifically on this page because you saw me upvote something on r/KotakuInAction or like a video from PSASitch or something like that. I'm not proud of this time period, where I read and watched a bit of Anti-SJW content. I'm glad to have moved on from this point of my life, and wish it hadn't happened in the first place. I don't really have any excuses, but appreciate understanding that I have grown as a person since this time.

I migrated a LOT of posts to this website for the sake of having them all in one place and under my control, rather than other websites'. I have not been able to look through the tens of thousands of posts (mostly upvotes/likes), but have done some basic filtering of these opinions I no longer hold. I'm open about the fact I once held these beliefs, but I don't need to be de facto promoting them by sharing them on this website. If you stumble across a post you think I'd rather not have on this site anymore, please reach out.

Radicalization

I believe a lot of things contributed to my radicalization, which happened sometime in the early 2020s. Ultimately I think I was just aware that I didn't really like the views I was being exposed to, the direction that media was trying to to pull me, and slowly over time just engaged less and less with that kind of content. I'd always been very economically leftist, so just needed to get over my edgy/cringe phase. I think what put the nail in the coffin was watching through the alt right playbook, a great series I highly recommend. I also started really enjoying a lot of leftist creators, like hasanabi, philosophy tube, and others. The people around me also affect my views, and after leaving college I think I interacted with nicer people on average. Of particular note here is my wife, who had their own political journey which has similarly culminated in us sort of having a positive feedback loop further and further left. Certain events like the BLM protests following George Floyd similarly cemented our position further and further left.

I actually want to also point out I've found a lot of people in this space to be very accepting of people who previously held problematic beliefs. It's largely why I feel comfortable (enough) having a lot of my history public both on this page and the site in general, and being able to describe how my political journey got me to where I am today, a very radical Leftist.

+ \ No newline at end of file diff --git a/garden/my-projects/index.html b/garden/my-projects/index.html index 4011f1060..72b82f859 100644 --- a/garden/my-projects/index.html +++ b/garden/my-projects/index.html @@ -6,14 +6,14 @@ My Projects | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

My Projects

72 words, ~0 minute read. Planted +

Skip to content

My Projects

72 words, ~0 minute read. Planted . Last tended to -.


Referenced by:Guide to Incrementals/What is Content?
Tagged by:Advent IncrementalBabble BudsCapture the CitadelDice ArmorGame Dev TreeIncremental SocialKronosOpti-SpeechOrchardPlanar PioneersProfectusV-ecs

I like making games and tools!

Games

Tools (and other non-games)

- +.


Referenced by:Guide to Incrementals/What is Content?
Tagged by:Advent IncrementalBabble BudsCapture the CitadelDice ArmorGame Dev TreeIncremental SocialKronosOpti-SpeechOrchardPlanar PioneersProfectusV-ecs

I like making games and tools!

Games

Tools (and other non-games)

+ \ No newline at end of file diff --git a/garden/neoliberalism/index.html b/garden/neoliberalism/index.html index 94b7ff7b9..ad17fdac2 100644 --- a/garden/neoliberalism/index.html +++ b/garden/neoliberalism/index.html @@ -6,14 +6,14 @@ Neoliberalism | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Neoliberalism

133 words, ~1 minute read. Planted +

Skip to content

Neoliberalism

133 words, ~1 minute read. Planted . Last tended to -.


Referenced by:IndividualismLocal CommunitiesTechnocracy

Neoliberalism is a conservative political philosophy that emphasizes Individualism and is resistant to change/progress. It became popular with the advent of President Raegan and his sweeping changes to the US economy and government (replacing the comparatively socialist polices of the New Deal and the Great Society), and affects both the Republican and Democratic US political parties.

I believe neoliberalism primarily affected the boomer generation and generation x. This lines up with trends in protest participation, which dipped during that time (by birth cohort) and picked back up starting with Millenials. The government is still largely controlled by those generations and still very neoliberal, despite increasingly progressive and left-leaning youth demographics.

Neoliberalism often supports ideas like meritocracies, calling them fair and just. However, by ignoring the context surrounding people's abilities and socioeconomic status, meritocracies end up merely reinforcing the current status quo - and if the current status quo is unfair or unjust, so too will be the meritocracy. Needless to say, we do not currently live in a society where the status quo is fair and just.

- +.


Referenced by:IndividualismLocal CommunitiesTechnocracy

Neoliberalism is a conservative political philosophy that emphasizes Individualism and is resistant to change/progress. It became popular with the advent of President Raegan and his sweeping changes to the US economy and government (replacing the comparatively socialist polices of the New Deal and the Great Society), and affects both the Republican and Democratic US political parties.

I believe neoliberalism primarily affected the boomer generation and generation x. This lines up with trends in protest participation, which dipped during that time (by birth cohort) and picked back up starting with Millenials. The government is still largely controlled by those generations and still very neoliberal, despite increasingly progressive and left-leaning youth demographics.

Neoliberalism often supports ideas like meritocracies, calling them fair and just. However, by ignoring the context surrounding people's abilities and socioeconomic status, meritocracies end up merely reinforcing the current status quo - and if the current status quo is unfair or unjust, so too will be the meritocracy. Needless to say, we do not currently live in a society where the status quo is fair and just.

+ \ No newline at end of file diff --git a/garden/network-of-knowledge/index.html b/garden/network-of-knowledge/index.html index 5350a8b44..cd77508ef 100644 --- a/garden/network-of-knowledge/index.html +++ b/garden/network-of-knowledge/index.html @@ -6,14 +6,14 @@ Network of Knowledge | The Paper Pilot - + - + - - - + + + @@ -53,9 +53,9 @@ -
Skip to content

Network of Knowledge

50 words, ~0 minute read. Planted -.


Referenced by:/nowOrchard

A theoretical concept for a federated protocol for people to write down their research, thoughts, etc. and link to other people's writings, such that it forms of network of all human thought

Existing Projects:

- +
Skip to content

Network of Knowledge

50 words, ~0 minute read. Planted +.


Referenced by:/nowOrchard

A theoretical concept for a federated protocol for people to write down their research, thoughts, etc. and link to other people's writings, such that it forms of network of all human thought

Existing Projects:

+ \ No newline at end of file diff --git a/garden/no-politics-rules/index.html b/garden/no-politics-rules/index.html index 38efbb47d..cdca4d11f 100644 --- a/garden/no-politics-rules/index.html +++ b/garden/no-politics-rules/index.html @@ -6,14 +6,14 @@ "No Politics" Rules | The Paper Pilot - + - + - - - + + + @@ -53,9 +53,10 @@ -
Skip to content

\"No Politics\" Rules

959 words, ~5 minute read. Planted -.


Referenced by:Incremental SocialKronos

Communities - be they discord servers, forums, message boards, etc. - tend to have rules, and you'll likely see the same rules come up often. One of these common rules is the "no politics" rule. These rules may vary slightly in wording, but all share in being highly contentious. These are easily the rules most often broken and most often fought over - for and against.

Apolitical spaces' appeal

Apolitical spaces are very appealing to many people, hence the proliferation of "no politics" rules. These communities represent anything from safe spaces to escapism, depending on the person. These are genuinely useful and absolutely crucial for some peoples' mental well-being.

Apathy

Naturally, some section of the population truly does not care about politics and does not wish to be bothered by discussions about it. However, political apathy is implicit endorsement of the existing power structures and is typically unique to those who are already benefitting from those power structures. Privilege doesn't make you feel special, it makes the world feel "normal". Therefore, political apathy is not a good reason to create a "no politics" rule, and enacting such a rule under this pretense is very much a political act in and of itself.

Mental health

Some political topics are deeply personal and emotionally exhausting to engage with, even (or especially) the important ones. For example, trans rights are a critical political issue, but demanding that trans people engage in political discourse about their right to exist amounts to a form of re-traumatization. Personally, I think a "be kind" or "no attacking others" rule suffices here though.

I think moderation should be heavy handed when it comes to protecting community members. The intolerant do not deserve the benefit of the doubt.

If we extend unlimited tolerance even to those who are intolerant, if we are not prepared to defend a tolerant society against the onslaught of the intolerant, then the tolerant will be destroyed, and tolerance with them. - Karl Raimund Popper, The Open Society and Its Enemies

Debate is ineffective

Debate is not about solving the issues in society and is typically rhetorical sport that cares more about winning the conversation than building consensus. It has been shown to be ineffective at changing minds, and even more rarely for the right reasons (underlying philosophy rather than rhetorical performance). Honestly, this is a great justification for disallowing politics, although later on I'll add some nuance to this point so it doesn't stifle legitimately constructive conversation.

The issues with banning politics

Everything is Political. So what "no politics" really means is very subjective and likely to differ between different moderators, and will definitely differ from at least some community members. What this really amounts to is banning controversial ideas. As described in How to radicalize a normie, that means both statements like "Nazis are bad" and "Nazis are good" can be apolitical, as the community has a consensus that Nazis are bad and the second statement is probably just a joke. But once something is controversial it becomes political, so a statement like "feminism is good" would be disallowed. In practice, since the non-controversial stances typically mean upholding existing power structures (like capitalism, patriarchy, and white supremacy), you reach a situation where conversative or fascist viewpoints are allowed (despite the "probably just a joke" argument gets weaker and weaker) but progressive statements aren't.

To be clear, I'm not saying those who add "no politics" rules support those power structures.

Moderators may also introduce their own biases, so even if you don't believe the above arguments will hold true for your community. There will still likely be uneven enforcement of the no politics rule due to the subjective differences in what is and isn't political. This will mean the line is still drawn somewhere, and wherever that line is will be a political statement, it just might not be clear where it's drawn to the members and even moderators of the community, which will cause confusion and conflict.

Alternatives to "no politics" rules

Needless to say, all communities are different and there's no "one size fits all" solution. That said, I think every rule of this list should apply to any and all communities:

  • Be kind to each other. Intolerance is prohibited and will be met with decisive action.

And that's it! That's the one rule that should fully encapsulate all the forms of speech you don't want in your community, without upholding existing power structures like capitalism, patriarchy, or white supremacy. It's simple, and certainly not novel, but it's all you need. It's similarity to the golden rule should be noted, as essentially every culture in the world has arrived at essentially the same conclusion, that this rule is of the upmost importance.

Decisive action, in this context, should probably mean muting or banning. Intolerance is very important to keep out of the community. You do not owe the person your time and effort for rehabilitation, and your community does not need to risk their own members' safety giving the benefit of the doubt.

If, for the sake of clarity, you would like a longer version, you can use this:

Be kind to each other. Intolerance, harassment, and speech or behavior that marginalizes or dehumanizes others based on their identity (e.g., race, gender, sexual orientation, religion, or disability) are strictly prohibited. This includes both direct attacks and the promotion of ideologies or statements that threaten the dignity and safety of marginalized groups.

Sensitive topics

Alright, I have one bonus rule for you. Certain topics are definitely more likely to have induced trauma in community members in the past. It likely makes sense to have communities that are not explicitly about discussing those kinds of topics relegate them to their own channel, called sensitive-topics or serious-discussion, and update the rules to include something like this:

Discussions of potentially traumatic topics (e.g., violence, abuse, or discrimination) should be approached with care and sensitivity, and moderators may restrict or redirect such discussions if they risk causing harm to community members.

You'll note I don't mention punishments here, but just how the situation should be handled by moderators. This is in contrast to explicitly calling for decisive action against the intolerant. This is because punishments are not good deterrents, so the main goal in reacting to a transgression should be undoing the damage and preventing future harm, which can typically be done without needing to punish the transgressor.

Decentralized Moderation

This whole conversation should be contextualized as referring to discrete communities with designated moderators. That's not the only option though! I personally think social media should incorporate porous or continuous communities through Digital Locality, which by necessity would then have Decentralized Moderation that makes essentially everything you've read here no longer relevant. Oops.

- +
Skip to content

"No Politics" Rules

960 words, ~5 minute read. Planted +. Last tended to +.


Referenced by:Incremental SocialKronos

Communities - be they discord servers, forums, message boards, etc. - tend to have rules, and you'll likely see the same rules come up often. One of these common rules is the "no politics" rule. These rules may vary slightly in wording, but all share in being highly contentious. These are easily the rules most often broken and most often fought over - for and against.

Apolitical spaces' appeal

Apolitical spaces are very appealing to many people, hence the proliferation of "no politics" rules. These communities represent anything from safe spaces to escapism, depending on the person. These are genuinely useful and absolutely crucial for some peoples' mental well-being.

Apathy

Naturally, some section of the population truly does not care about politics and does not wish to be bothered by discussions about it. However, political apathy is implicit endorsement of the existing power structures and is typically unique to those who are already benefitting from those power structures. Privilege doesn't make you feel special, it makes the world feel "normal". Therefore, political apathy is not a good reason to create a "no politics" rule, and enacting such a rule under this pretense is very much a political act in and of itself.

Mental health

Some political topics are deeply personal and emotionally exhausting to engage with, even (or especially) the important ones. For example, trans rights are a critical political issue, but demanding that trans people engage in political discourse about their right to exist amounts to a form of re-traumatization. Personally, I think a "be kind" or "no attacking others" rule suffices here though.

I think moderation should be heavy handed when it comes to protecting community members. The intolerant do not deserve the benefit of the doubt.

If we extend unlimited tolerance even to those who are intolerant, if we are not prepared to defend a tolerant society against the onslaught of the intolerant, then the tolerant will be destroyed, and tolerance with them. - Karl Raimund Popper, The Open Society and Its Enemies

Debate is ineffective

Debate is not about solving the issues in society and is typically rhetorical sport that cares more about winning the conversation than building consensus. It has been shown to be ineffective at changing minds, and even more rarely for the right reasons (underlying philosophy rather than rhetorical performance). Honestly, this is a great justification for disallowing politics, although later on I'll add some nuance to this point so it doesn't stifle legitimately constructive conversation.

The issues with banning politics

Everything is Political. So what "no politics" really means is very subjective and likely to differ between different moderators, and will definitely differ from at least some community members. What this really amounts to is banning controversial ideas. As described in How to radicalize a normie, that means both statements like "Nazis are bad" and "Nazis are good" can be apolitical, as the community has a consensus that Nazis are bad and the second statement is probably just a joke. But once something is controversial it becomes political, so a statement like "feminism is good" would be disallowed. In practice, since the non-controversial stances typically mean upholding existing power structures (like capitalism, patriarchy, and white supremacy), you reach a situation where conversative or fascist viewpoints are allowed (despite the "probably just a joke" argument gets weaker and weaker) but progressive statements aren't.

To be clear, I'm not saying those who add "no politics" rules support those power structures.

Moderators may also introduce their own biases, so even if you don't believe the above arguments will hold true for your community. There will still likely be uneven enforcement of the no politics rule due to the subjective differences in what is and isn't political. This will mean the line is still drawn somewhere, and wherever that line is will be a political statement, it just might not be clear where it's drawn to the members and even moderators of the community, which will cause confusion and conflict.

Alternatives to "no politics" rules

Needless to say, all communities are different and there's no "one size fits all" solution. That said, I think every rule of this list should apply to any and all communities:

  1. Be kind to each other. Intolerance is prohibited and will be met with decisive action.

And that's it! That's the one rule that should fully encapsulate all the forms of speech you don't want in your community, without upholding existing power structures like capitalism, patriarchy, or white supremacy. It's simple, and certainly not novel, but it's all you need. It's similarity to the golden rule should be noted, as essentially every culture in the world has arrived at essentially the same conclusion, that this rule is of the upmost importance.

Decisive action, in this context, should probably mean muting or banning. Intolerance is very important to keep out of the community. You do not owe the person your time and effort for rehabilitation, and your community does not need to risk their own members' safety giving the benefit of the doubt.

If, for the sake of clarity, you would like a longer version, you can use this:

Be kind to each other. Intolerance, harassment, and speech or behavior that marginalizes or dehumanizes others based on their identity (e.g., race, gender, sexual orientation, religion, or disability) are strictly prohibited. This includes both direct attacks and the promotion of ideologies or statements that threaten the dignity and safety of marginalized groups.

Sensitive topics

Alright, I have one bonus rule for you. Certain topics are definitely more likely to have induced trauma in community members in the past. It likely makes sense to have communities that are not explicitly about discussing those kinds of topics relegate them to their own channel, called sensitive-topics or serious-discussion, and update the rules to include something like this:

Discussions of potentially traumatic topics (e.g., violence, abuse, or discrimination) should be approached with care and sensitivity, and moderators may restrict or redirect such discussions if they risk causing harm to community members.

You'll note I don't mention punishments here, but just how the situation should be handled by moderators. This is in contrast to explicitly calling for decisive action against the intolerant. This is because punishments are not good deterrents, so the main goal in reacting to a transgression should be undoing the damage and preventing future harm, which can typically be done without needing to punish the transgressor.

Decentralized Moderation

This whole conversation should be contextualized as referring to discrete communities with designated moderators. That's not the only option though! I personally think social media should incorporate porous or continuous communities through Digital Locality, which by necessity would then have Decentralized Moderation that makes essentially everything you've read here no longer relevant. Oops.

+ \ No newline at end of file diff --git a/garden/nostr/index.html b/garden/nostr/index.html index 1c92e653a..d4ee678d8 100644 --- a/garden/nostr/index.html +++ b/garden/nostr/index.html @@ -6,14 +6,14 @@ Nostr | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Nostr

52 words, ~0 minute read. Planted +

Skip to content

Nostr

52 words, ~0 minute read. Planted . Last tended to -.


Referenced by:Decentralized Social Media
Tags:Decentralized

Nostr is the largest currently existing example of a fully Decentralized Social Media . It fixes the pick a server problem the Fediverse has with a properly Decentralized Identity .

Unfortunately, the network has a culture problem - its been primarily built by and caters to the cryptocurrency community and alt right. It'll be difficult to gain broad adoption as anyone using the platform will have to take care to explain how they're using nostr but aren't alt right.

- +.


Referenced by:Decentralized Social Media
Tags:Decentralized

Nostr is the largest currently existing example of a fully Decentralized Social Media . It fixes the pick a server problem the Fediverse has with a properly Decentralized Identity .

Unfortunately, the network has a culture problem - its been primarily built by and caters to the cryptocurrency community and alt right. It'll be difficult to gain broad adoption as anyone using the platform will have to take care to explain how they're using nostr but aren't alt right.

+ \ No newline at end of file diff --git a/garden/objectivity/index.html b/garden/objectivity/index.html index 359da3d4d..80d503418 100644 --- a/garden/objectivity/index.html +++ b/garden/objectivity/index.html @@ -6,14 +6,14 @@ Objectivity | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Objectivity

589 words, ~3 minute read. Planted +

Skip to content

Objectivity

589 words, ~3 minute read. Planted . Last tended to -.


Referenced by:Everything is PoliticalFilter BubblesScientific Constructivism

Objectivity is a myth. All we have are our subjective experiences, which are shaped by our environments and it's Social Constructs. Often something appearing objective more likely means its biased towards either your pre-conceived opinion, or the "status quo" opinion of the society or culture the work was created in.

When a social construct becomes sufficiently ingrained within society to the point it's not recognized as a construct, it can begin to be considered an "objective truth", which can lead to harmful results.

These social constructs form Echo Chambers around the entire society. In this way, echo chambers fractal within each other. That's not inherently a bad thing, but it's often difficult to recognize echo chambers from inside, and we're all ultimately inside at least one.

In practice, the idea that objectivity doesn't exist doesn't really impact anything. Our shared experiences are similar enough that our truths about most every day things are compatible. Where this most applies is when there's an argument between two people who are reaching different conclusions despite the same level of knowledge about the topic. In theory, you could probably find a shared common ground and determine that specific logical step in which you diverge. That divergence may be explained by our subjective perspectives on the world, mixed with our personal values. However, a side may claim their side of the divergence is the correct one due to some "objective truth". This is simply not so, but is all too often used to justify bigoted arguments.

Zoe Bee, in The Language War of Politics: How Metaphors Shape Our Thinking, discusses how reality is subjective and shaped by our experiences. This is framed by how metaphors take advantage of this concept to direct how we think about the tenor (the subject of the metaphor).

Economics

"Objective Economics" Isn't discusses how objectivity doesn't exist (at least in the context of economics), and how those who claim there is are doing so maliciously.

Yes, neoclassical/marginalist economics — and the Austrian economics to which Carroll predictably adheres — is technically “objective” in the sense that it’s a set of rules that objectively produce the same results from a given set of inputs every time. But the axioms of Austrian economics are, in themselves, trivially — or even circularly — true. What matters is the application of those axioms in a manner sufficiently sophisticated to generate meaningful statements about complex economic phenomena. The assumptions governing that application, and even what questions to ask, reflect value judgments. Any economic paradigm involves such choices, and the choices made will render it more relevant for some purposes and less relevant for others. Those choices are unavoidably political.

They discuss how claiming objectivity is used to add credibility to an argument. However, these "objective" arguments are only true within a specific framework of rules and restrictions, which they only suggest but don't prove matches reality. They effectively erase important context that are inconvenient for their politically motivated argument, and by doing so deliberately draw wrong conclusions.

"Dress is not an art project. It's a language, and you're babbling incoherently"

CJ the X discusses in How Jordan Peterson's Suits Taught Me Fashion how the idea that art is subjective hindered his ability to learn fashion as a teenager. He uses the above quote to articulate how contemporary values replacing the oppressive but comparatively well defined fashion values did him a disservice. He was essentially no longer able to learn and get advice on fashion other than through his own individual experimentation. He compares it to a language, where you can learn the grammar and vocabulary, but still be unable to make sensical sentences unless you understand the how and why people put these words together - like understanding the different articles of clothing, but not the why and how they get paired together. Arguing for fashion as a language, and that despite its subjectivity there's still necessarily a learned social component, enables people to be able to teach fashion without feeling like their just upholding old bigoted values. It's also a brilliant argument for why Social Constructs can be and are useful.

He also describes the history of fashion's values, and how previously there was the idea of a singular "objective" sense of fashion, and that those who disagree are just incorrect. Essentially that meant the goal of fashion was to look like how the elites look. He argues that today fashion is still trying to look how the elites look, but now the elites are fractured - academic elites have their own fashion from, say, the elites of hip hop. This actually sounds a lot like Butler's argument for Gender Performativity.

- +.


Referenced by:Everything is PoliticalFilter BubblesScientific Constructivism

Objectivity is a myth. All we have are our subjective experiences, which are shaped by our environments and it's Social Constructs. Often something appearing objective more likely means its biased towards either your pre-conceived opinion, or the "status quo" opinion of the society or culture the work was created in.

When a social construct becomes sufficiently ingrained within society to the point it's not recognized as a construct, it can begin to be considered an "objective truth", which can lead to harmful results.

These social constructs form Echo Chambers around the entire society. In this way, echo chambers fractal within each other. That's not inherently a bad thing, but it's often difficult to recognize echo chambers from inside, and we're all ultimately inside at least one.

In practice, the idea that objectivity doesn't exist doesn't really impact anything. Our shared experiences are similar enough that our truths about most every day things are compatible. Where this most applies is when there's an argument between two people who are reaching different conclusions despite the same level of knowledge about the topic. In theory, you could probably find a shared common ground and determine that specific logical step in which you diverge. That divergence may be explained by our subjective perspectives on the world, mixed with our personal values. However, a side may claim their side of the divergence is the correct one due to some "objective truth". This is simply not so, but is all too often used to justify bigoted arguments.

Zoe Bee, in The Language War of Politics: How Metaphors Shape Our Thinking, discusses how reality is subjective and shaped by our experiences. This is framed by how metaphors take advantage of this concept to direct how we think about the tenor (the subject of the metaphor).

Economics

"Objective Economics" Isn't discusses how objectivity doesn't exist (at least in the context of economics), and how those who claim there is are doing so maliciously.

Yes, neoclassical/marginalist economics — and the Austrian economics to which Carroll predictably adheres — is technically “objective” in the sense that it’s a set of rules that objectively produce the same results from a given set of inputs every time. But the axioms of Austrian economics are, in themselves, trivially — or even circularly — true. What matters is the application of those axioms in a manner sufficiently sophisticated to generate meaningful statements about complex economic phenomena. The assumptions governing that application, and even what questions to ask, reflect value judgments. Any economic paradigm involves such choices, and the choices made will render it more relevant for some purposes and less relevant for others. Those choices are unavoidably political.

They discuss how claiming objectivity is used to add credibility to an argument. However, these "objective" arguments are only true within a specific framework of rules and restrictions, which they only suggest but don't prove matches reality. They effectively erase important context that are inconvenient for their politically motivated argument, and by doing so deliberately draw wrong conclusions.

"Dress is not an art project. It's a language, and you're babbling incoherently"

CJ the X discusses in How Jordan Peterson's Suits Taught Me Fashion how the idea that art is subjective hindered his ability to learn fashion as a teenager. He uses the above quote to articulate how contemporary values replacing the oppressive but comparatively well defined fashion values did him a disservice. He was essentially no longer able to learn and get advice on fashion other than through his own individual experimentation. He compares it to a language, where you can learn the grammar and vocabulary, but still be unable to make sensical sentences unless you understand the how and why people put these words together - like understanding the different articles of clothing, but not the why and how they get paired together. Arguing for fashion as a language, and that despite its subjectivity there's still necessarily a learned social component, enables people to be able to teach fashion without feeling like their just upholding old bigoted values. It's also a brilliant argument for why Social Constructs can be and are useful.

He also describes the history of fashion's values, and how previously there was the idea of a singular "objective" sense of fashion, and that those who disagree are just incorrect. Essentially that meant the goal of fashion was to look like how the elites look. He argues that today fashion is still trying to look how the elites look, but now the elites are fractured - academic elites have their own fashion from, say, the elites of hip hop. This actually sounds a lot like Butler's argument for Gender Performativity.

+ \ No newline at end of file diff --git a/garden/open-source/index.html b/garden/open-source/index.html index 967219c6b..6d339415a 100644 --- a/garden/open-source/index.html +++ b/garden/open-source/index.html @@ -6,14 +6,14 @@ Open Source | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Open Source

25 words, ~0 minute read. Planted +

Skip to content

Open Source

25 words, ~0 minute read. Planted . Last tended to -.


Referenced by:Advent IncrementalCinnyCommuneDice ArmorForgejoGame Dev TreeLogseqMbinPlanar PioneersProfectusSynapseVitepressWeird

Projects with the source code publicly accessible

Typically also grants users the right to modify the code and redistribute those changes, depending on the license

- +.


Referenced by:Advent IncrementalCinnyCommuneDice ArmorForgejoGame Dev TreeLogseqMbinPlanar PioneersProfectusSynapseVitepressWeird

Projects with the source code publicly accessible

Typically also grants users the right to modify the code and redistribute those changes, depending on the license

+ \ No newline at end of file diff --git a/garden/opti-speech/index.html b/garden/opti-speech/index.html index 31fa225ea..a5882e9e5 100644 --- a/garden/opti-speech/index.html +++ b/garden/opti-speech/index.html @@ -6,14 +6,14 @@ Opti-Speech | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Opti-Speech

312 words, ~2 minute read. Planted +

Skip to content

Opti-Speech

312 words, ~2 minute read. Planted . Last tended to -.


Tags:My Projects

In college I continued development on the Opti-Speech project, originally built alongside the scientific paper Opti-speech: a real-time, 3d visual feedback system for speech training

The Original Project

The Optispeech project involves designing and testing a real-time tongue model that can be viewed in a transparent head while a subject talks — for the purposes of treating speech errors and teaching foreign language sounds. This work has been conducted in partnership with Vulintus and with support from the National Institutes of Health (NIH).

This video shows a talker with WAVE sensors placed on the tongue hitting a virtual target sphere located at the alveolar ridge. When an alveolar consonant is hit (e.g., /s/, /n/, /d/) the sphere changes color from red to green.

This video shows an American talker learning a novel sound not found in English. When the post-alveolar consonant is hit, the target sphere changes color from red to green. Here, the NDI WAVE system serves as input.

My Work

As the sole programmer at UT Dallas Speech Production Lab at the time, my changes involved updating to a more modern version of Unity, improving the interface, in general cleaning up tech debt so it can more easily support new features, and added support for additional EMA systems, namely the Carstens AG501.

In addition, the program now includes documentation and unit tests to improve program stability and maintainability going forward.

- +.


Tags:My Projects

In college I continued development on the Opti-Speech project, originally built alongside the scientific paper Opti-speech: a real-time, 3d visual feedback system for speech training

The Original Project

The Optispeech project involves designing and testing a real-time tongue model that can be viewed in a transparent head while a subject talks — for the purposes of treating speech errors and teaching foreign language sounds. This work has been conducted in partnership with Vulintus and with support from the National Institutes of Health (NIH).

This video shows a talker with WAVE sensors placed on the tongue hitting a virtual target sphere located at the alveolar ridge. When an alveolar consonant is hit (e.g., /s/, /n/, /d/) the sphere changes color from red to green.

This video shows an American talker learning a novel sound not found in English. When the post-alveolar consonant is hit, the target sphere changes color from red to green. Here, the NDI WAVE system serves as input.

My Work

As the sole programmer at UT Dallas Speech Production Lab at the time, my changes involved updating to a more modern version of Unity, improving the interface, in general cleaning up tech debt so it can more easily support new features, and added support for additional EMA systems, namely the Carstens AG501.

In addition, the program now includes documentation and unit tests to improve program stability and maintainability going forward.

+ \ No newline at end of file diff --git a/garden/orchard/index.html b/garden/orchard/index.html index 1bbf00c26..b86c91c05 100644 --- a/garden/orchard/index.html +++ b/garden/orchard/index.html @@ -6,14 +6,14 @@ Orchard | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Orchard

634 words, ~3 minute read. Planted +

Skip to content

Orchard

634 words, ~3 minute read. Planted . Last tended to -.


Referenced by:/now
Tags:My Projects

This is an app I'm designing and at least building a mock for. I'd like it to either get built directly into Commune or integrate with it. The purpose of the app is to organize and grow a Network of Knowledge (or Digital Garden) sorted by topic. It achieves this through a concept called message gardening, the process of converting casual conversations into formal, referenceable stores of knowledge.

The problem I have that I'm trying to solve is having a lot of conversations about various topics stretching back far into the past and across many platforms. I often want to review something I said on a given topic and find it difficult to do so. This app would make it far easier to retrieve my notes on any topic. It's different than a traditional note-taking app because it works with conversations directly, which is how my "notes" on a topic initially start out as. As a secondary effect, this will also fix some of the issues described in the chat glue comic. I'd like it to eventually support even more of the ideas proposed in that comment, like replies and reactions to parts of a message.

The main way you interact with the app is by conversing. As you converse in your group chats and DMs, which are technically through matrix but can bridge to other platforms like discord, you can specify topic changes. These will break the conversation up into pieces, and each piece gets added to each of the topics it was about (with links to the convo from before and after that one). If a piece was about multiple topics it forms a link between those topics and considers them in some way related. These links are represented as lines in the topics graph, and cause the topics to be physically closer within the graph. Topics can use slashes to indicate hierarchy, which will also place them next to each other in the graph.

Non-conversation notes

In addition to including conversations, I want to support freeform notes that also discuss one or more topics. Through leaf's compositional structure, in theory any entity should be able to be added to the network.

Another type of non-conversation note could be excerpts from online articles, which could be automatically cited.

When allowing these kinds of notes, users should be encouraged to split notes as small as possible. This allows us to avoid needing something like Garden-RSS by just showing that a note has updated, and showing the new content.

Communal Networks

By integrating with commune on the server side, the network could be maintained by the entire community, allowing any (trusted) members to mark topic changes. This has the benefit of making maintenance easier on any individual, but also it means users wanting to catch up on the conversations can now do so via the graph, ignoring any conversations that don't mention any topics that user doesn't particularly care about.

Federation

Allow clients to "follow" those communal networks, replicating them locally and merging them together (aliasing similar topics as necessary). This allows users to get very large networks much more easily, and further incentivizes contributing to the communal networks.

LLMs

A local LLM could assist in marking topic changes automatically, allowing you to get the benefits of the conversation being broken up for catching up even while on a non-commune chat.

LLMs could also be given the topics as context and be able to query the network for knowledge.

Tech Stack

The client will be a matrix client that stores all the messages locally. It'll use Fedi v2 to store the messages and other data, making the whole app Local-First Software. The rest of the app will be a web-based UI, using Neutralino.js or an alternative.

Actually, tauri apparently doesn't require rust per-say, and has things like mobile support and a better dev experience.

The server will be something that ensures commune servers can share topic changes across the community.

Consider using Animata components

- +.


Referenced by:/now
Tags:My Projects

This is an app I'm designing and at least building a mock for. I'd like it to either get built directly into Commune or integrate with it. The purpose of the app is to organize and grow a Network of Knowledge (or Digital Garden) sorted by topic. It achieves this through a concept called message gardening, the process of converting casual conversations into formal, referenceable stores of knowledge.

The problem I have that I'm trying to solve is having a lot of conversations about various topics stretching back far into the past and across many platforms. I often want to review something I said on a given topic and find it difficult to do so. This app would make it far easier to retrieve my notes on any topic. It's different than a traditional note-taking app because it works with conversations directly, which is how my "notes" on a topic initially start out as. As a secondary effect, this will also fix some of the issues described in the chat glue comic. I'd like it to eventually support even more of the ideas proposed in that comment, like replies and reactions to parts of a message.

The main way you interact with the app is by conversing. As you converse in your group chats and DMs, which are technically through matrix but can bridge to other platforms like discord, you can specify topic changes. These will break the conversation up into pieces, and each piece gets added to each of the topics it was about (with links to the convo from before and after that one). If a piece was about multiple topics it forms a link between those topics and considers them in some way related. These links are represented as lines in the topics graph, and cause the topics to be physically closer within the graph. Topics can use slashes to indicate hierarchy, which will also place them next to each other in the graph.

Non-conversation notes

In addition to including conversations, I want to support freeform notes that also discuss one or more topics. Through leaf's compositional structure, in theory any entity should be able to be added to the network.

Another type of non-conversation note could be excerpts from online articles, which could be automatically cited.

When allowing these kinds of notes, users should be encouraged to split notes as small as possible. This allows us to avoid needing something like Garden-RSS by just showing that a note has updated, and showing the new content.

Communal Networks

By integrating with commune on the server side, the network could be maintained by the entire community, allowing any (trusted) members to mark topic changes. This has the benefit of making maintenance easier on any individual, but also it means users wanting to catch up on the conversations can now do so via the graph, ignoring any conversations that don't mention any topics that user doesn't particularly care about.

Federation

Allow clients to "follow" those communal networks, replicating them locally and merging them together (aliasing similar topics as necessary). This allows users to get very large networks much more easily, and further incentivizes contributing to the communal networks.

LLMs

A local LLM could assist in marking topic changes automatically, allowing you to get the benefits of the conversation being broken up for catching up even while on a non-commune chat.

LLMs could also be given the topics as context and be able to query the network for knowledge.

Tech Stack

The client will be a matrix client that stores all the messages locally. It'll use Fedi v2 to store the messages and other data, making the whole app Local-First Software. The rest of the app will be a web-based UI, using Neutralino.js or an alternative.

Actually, tauri apparently doesn't require rust per-say, and has things like mobile support and a better dev experience.

The server will be something that ensures commune servers can share topic changes across the community.

Consider using Animata components

+ \ No newline at end of file diff --git a/garden/personality/index.html b/garden/personality/index.html index 73419313b..3e64c84c9 100644 --- a/garden/personality/index.html +++ b/garden/personality/index.html @@ -6,14 +6,14 @@ Personality | The Paper Pilot - + - + - - - + + + @@ -53,9 +53,9 @@ -
Skip to content

Personality

143 words, ~1 minute read. Planted -.


I think personality is best explained with a combination of Social Identity Theory and Self Categorization Theory

  • Social Identity Theory
    • Posits that significant amount of our personality is derived from our membership in various social groups
    • People categorize themselves and others into groups based on nationality, gender, profession, interests, etc.
    • The groups one feels they most identity with end up shaping one's behaviors
    • Also leads to discrimination and out-group homogeneity
  • Self Categorization Theory
    • People act in ways that they perceive as typical for the members of the group they identify with
    • Can lead to viewing oneself as an embodiment of the group prototype rather than a unique individual
  • I believe people adopt core identities and then subconsciously use their perception of how people with those identities as a mnemonic for how they should behave
  • Gender Performativity maps cleanly onto these theories
- +
Skip to content

Personality

143 words, ~1 minute read. Planted +.


I think personality is best explained with a combination of Social Identity Theory and Self Categorization Theory

  • Social Identity Theory
    • Posits that significant amount of our personality is derived from our membership in various social groups
    • People categorize themselves and others into groups based on nationality, gender, profession, interests, etc.
    • The groups one feels they most identity with end up shaping one's behaviors
    • Also leads to discrimination and out-group homogeneity
  • Self Categorization Theory
    • People act in ways that they perceive as typical for the members of the group they identify with
    • Can lead to viewing oneself as an embodiment of the group prototype rather than a unique individual
  • I believe people adopt core identities and then subconsciously use their perception of how people with those identities as a mnemonic for how they should behave
  • Gender Performativity maps cleanly onto these theories
+ \ No newline at end of file diff --git a/garden/planar-pioneers/index.html b/garden/planar-pioneers/index.html index c42ea8962..905dca85a 100644 --- a/garden/planar-pioneers/index.html +++ b/garden/planar-pioneers/index.html @@ -6,14 +6,14 @@ Planar Pioneers | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Planar Pioneers

25 words, ~0 minute read. Planted +

Skip to content

Planar Pioneers

25 words, ~0 minute read. Planted . Last tended to -.


Tags:My ProjectsProfectus

Play it here!

An Open Source game designed to show off Profectus' dynamic layer system!

The TV Tropes page on this game mentions some of the cool things about this game

- +.


Tags:My ProjectsProfectus

Play it here!

An Open Source game designed to show off Profectus' dynamic layer system!

The TV Tropes page on this game mentions some of the cool things about this game

+ \ No newline at end of file diff --git a/garden/police-abolition/index.html b/garden/police-abolition/index.html index 410d781f9..815b6698d 100644 --- a/garden/police-abolition/index.html +++ b/garden/police-abolition/index.html @@ -6,14 +6,14 @@ Police Abolition | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Police Abolition

1641 words, ~9 minute read. Planted +

Skip to content

Police Abolition

1641 words, ~9 minute read. Planted . Last tended to -.


Referenced by:AnarchismConsensus DemocracyMy Political Beliefs

I'm a supporter of the police abolition movement, which calls for police and prisons to be abolished. It argues that there are many inherent problems with policing and incarcerating people that cannot be fixed with just further training or restrictions - the entire system must be entirely abolished. In this way, it is a more extreme version of the police reform or defund the police movements. The movement also posits that there are alternatives to policing and incarceration that can be more effective at reducing crime.

What is police abolition?

Just to make sure we're all on the same page as to what police abolition means and involves, I'll be using some definitions from Critical Reach:

The prison industrial complex (PIC) is a term we use to describe the overlapping interests of government and industry that use surveillance, policing, and imprisonment as solutions to economic, social and political problems.

PIC abolition is a political vision with the goal of eliminating imprisonment, policing, and surveillance and creating lasting alternatives to punishment and imprisonment.

I'll generally just say police or prison abolition, but I'm still referring to pieces of PIC abolition.

Why abolish police?

There are a variety of reasons for abolishing the police, from its controversial origins to its pervasive discrimination to its overall lack of effectiveness. Ultimately though, I would argue this movement stems from anarchistic principles and values. Anarchism posits that no person should hold power over another (a simplification sufficient for this document), which would include the use of force or imprisonment. Anarchists argue the State has no right to exist, let alone that it has no right to call it's violence legitimate. From this premise, any form of policing or incarceration is unjust. However, let's explore additional problems within the specific context of the US:

Origins of policing

The initial implementation of the police in the US was inspired both by the systems they experienced across the pond as well as the bands of slave catchers that were present at the time. The fact policing and incarceration as concepts had to be invented and introduced to people who were already existing just fine is telling enough, and the fact they were introduced to bring slaves back to their owners is even more telling. These origins have ingrained racism into the entire system, and they are still evident today when looking at racial profiling, incarceration rates, etc.

Throughout their history police have, in practice, protected "property" (which slaves were considered to be at the time), not people. In a broader sense, they were a tool of the capitalist elite. That's why the Supreme Court ruled that police do not actually have an obligation to protect nor serve citizens and why early cops were also strike breakers.

While the origins of an institution don't necessarily dictate how it is structured and operated hundreds of years later, they do give insight into how the institution was designed and what purposes/roles it was actually filling. Today, thanks to various forms of "copaganda" in media, there's rhetoric that people should support and appreciate the police, that they are fair and effective and protect us from crime and villainy. As we'll continue to describe, I think the police are much more similar to their roots than the fiction they're portrayed as.

Discriminating against the poor

The police are designed to reinforce the capitalist status quo; the "law and order" they uphold is less so to do with ensuring life is fair and safe for all, but rather to keep the working class in check so the capitalist class are safe and secure. This is most evident by looking at how many laws primarily affect the poor and how rarely laws are enforced when the perpetrator is a capitalist.

"The law, in its majestic equality, forbids rich and poor alike to sleep under bridges, to beg in the streets, and to steal their bread."
Anatole France

Property crime lead to over 750,000 arrests in 2019. Wage theft, which according to a 2014 study may account for up to $50 Billion stolen, is a civil matter that doesn't lead to any arrests. In fact, white collar misdeeds are often not classified as criminal offenses - that's why after the 2008 housing market crash that devastated millions, only 1 banker was arrested and it was for something relatively trivial compared to the actual crash.

Even when it is a criminal offense, white collar crime is rarely punished. A lot of societal elites get away with horrendous misdeeds essentially out in the open. In fact, prosecuting the rich is so out of the norm that a rookie cop arresting Justin Timberlake caused a kerfuffle online because of just how much people like Justin aren't supposed to get arrested.

As a side note, there's a double standard here where rich are treated differently from poor people when they're the perpetrator of the crime, but not when they're the victim. If you look online for opinions on whether stealing from the rich to give to the poor is actually justified, you'll get a fairly overwhelming response that "theft is theft" and the context within which the theft occurred is not relevant. I think it's important to keep in mind the context of how the rich have rigged the system to consolidate wealth in the hands of as few as possible, and the impact that has had on society. On other issues, people are just fine dealing with nuance, like how violence is justified when it's self defense. I believe our society has been deliberately shaped to have the value that the victim being poor vs rich shouldn't matter, specifically because it benefits the rich.

Racism

The PIC has not shaken off the racism ingrained within its roots. Arrests are not proportional to actual crime rates, disproportionately affecting people of color - including when the cops themselves are black. Additionally, laws have been introduced throughout the history of the US that were explicitly designed to affect minorities, like the Jim Crow laws or the entirety of Nixon's war on drugs (a victimless "crime").

The police are an active threat to black people, who are 3x as likely to be shot and killed from the police without presenting a threat. That makes cops people to be avoided and who cannot be relied upon in an emergency. Even calling the police yourself is a risk.

Cost

The government spends hundreds of billions of dollars on the incarceral system, an absolutely profound amount of money that could make enormous differences had it been put to social services instead.

The prison system has for profit private prisons with minimum occupancy clauses that cost taxpayers money if we don't arrest enough people. This is a gross financial incentive to arrest more people, and it disincentivizes actual rehabilitation. These contribute to the US' incredibly high recidivism rates.

Ineffectiveness at stopping crime

Most crimes performed are out of necessity, not malice. For example, few would be stealing baby formula or bread if it weren't for our economic system introducing artificial scarcity to keep prices going up.

America has the highest incarceration rate in the world, for a variety of the reasons mentioned in this document. Yet, the fear of punishment and imprisonment does not seem to have the effect of discouraging crime. Indeed, increasing incarceration does not decrease crime.

Criminal officers

Officers themselves perpetrate a lot of crime (and I suspect there's a lot of police crimes that doesn't get reported), including 1/3 of all murders that involve a stranger, and are typically protected by a corrupt system with the strongest union in the nation (often attributed to the union serving the interests of capital, rather than workers like labor unions). In particular, officers have incredibly high rates of interspousal conflicts. Therefore, abolitionism is the only solution to gender-based violence.

How to abolish police

There are many ways to reduce the need of police until it's eventually zero. Immediately, perpetratore of victimless crimes should be let out of prison. You can also reduce most root causes of crime, rather than spending the money on incarcerating the perpetrators.

Crime reduction

Abolitionists still want to ensure public safety, just not through policing and incarceration. They believe, since most crime is not born of malice, that improving society by ensuring everyone's needs are met would evaporate the majority of crimes as well - at least as many as are prevented by the current system. Police are incredibly over funded, enough to buy things like surplus tanks from the US military. That money can instead go to social programs that would solve the root causes that lead to crimes.

Societies can and will find alternative ways of preventing any specific crime. An often used example is if you have a drunk friend who is about to drive home, you typically will help get them a ride (driving yourself if you're sober, or calling them a cab or uber otherwise) rather than calling the police on them. Abolitionism finds policing as only required by those who lack the political imagination to find other solutions - basically, cure the diseases rather than treat the symptoms. At a systemic level, drunk driving can be reduced or eliminated by improving public transit.

Dangerous incidents

With the police abolished, there are likely to still be cases where an individual is a danger to themselves or others. For these situations, there are ideas on how to resolve it without state sanctioned violence, that typically focus on local communities setting up alternative resources. Mobile crisis teams are one such alternative, although not without similar concerns regarding their authority to forcibly incarcerate people in mental health hospitals. There are a lot of alternatives out there, but they're typically specific to local communities and don't really have a "one size fits all" solution. Here's an article about a couple such initiatives, and this article linked earlier also discusses some specific local initiatives.

Another criticism of prison abolitionism specifically is What do you do with the murderers and rapists?, but as that article describes: we already don't incarcerate many murderers and rapists, especially the significant amount of murderers and rapists who are also officers. It argues the incarceral system already fails in this regard, and focuses on punishing the perpetrator rather than helping the victims, which is something we could do without incarceration.

Consequences

While punishments are not good deterrents, some consequences for crimes are still justified and can be enforced without requiring incarceration. A victim may be "made whole" (have the damage reversed to the best of our ability) at expense of the perpetrator, or the society itself (using resources its no longer spending on police or prison). If there's a material cause for the crime having taken place, e.g. a hungry person stealing food, those material conditions can be improved. For cases where the perpetrator is chronically exhibiting anti-social behavior, a trip to a rehabilitation facility, which would be operated significantly differently from the PIC, could be warranted. Stuff like anger management courses or resources to help kick addictions would naturally still be present in a society without prisons.

Further reading

I have not finished reading it yet myself, but I recommend We Do This ‘Til We Free Us by Mariame Kaba based on this NBC article on the book and author.

How police make up the law by Philosophy Tube is a very well produced look at how police got their de facto supreme authority, and it's implications. They have several other videos on the police I recommend, and any other videos they've made 😃.

Abolition notes contains a lot of public documents and guides on prison abolition and related leftist causes.

- +.


Referenced by:AnarchismConsensus DemocracyMy Political Beliefs

I'm a supporter of the police abolition movement, which calls for police and prisons to be abolished. It argues that there are many inherent problems with policing and incarcerating people that cannot be fixed with just further training or restrictions - the entire system must be entirely abolished. In this way, it is a more extreme version of the police reform or defund the police movements. The movement also posits that there are alternatives to policing and incarceration that can be more effective at reducing crime.

What is police abolition?

Just to make sure we're all on the same page as to what police abolition means and involves, I'll be using some definitions from Critical Reach:

The prison industrial complex (PIC) is a term we use to describe the overlapping interests of government and industry that use surveillance, policing, and imprisonment as solutions to economic, social and political problems.

PIC abolition is a political vision with the goal of eliminating imprisonment, policing, and surveillance and creating lasting alternatives to punishment and imprisonment.

I'll generally just say police or prison abolition, but I'm still referring to pieces of PIC abolition.

Why abolish police?

There are a variety of reasons for abolishing the police, from its controversial origins to its pervasive discrimination to its overall lack of effectiveness. Ultimately though, I would argue this movement stems from anarchistic principles and values. Anarchism posits that no person should hold power over another (a simplification sufficient for this document), which would include the use of force or imprisonment. Anarchists argue the State has no right to exist, let alone that it has no right to call it's violence legitimate. From this premise, any form of policing or incarceration is unjust. However, let's explore additional problems within the specific context of the US:

Origins of policing

The initial implementation of the police in the US was inspired both by the systems they experienced across the pond as well as the bands of slave catchers that were present at the time. The fact policing and incarceration as concepts had to be invented and introduced to people who were already existing just fine is telling enough, and the fact they were introduced to bring slaves back to their owners is even more telling. These origins have ingrained racism into the entire system, and they are still evident today when looking at racial profiling, incarceration rates, etc.

Throughout their history police have, in practice, protected "property" (which slaves were considered to be at the time), not people. In a broader sense, they were a tool of the capitalist elite. That's why the Supreme Court ruled that police do not actually have an obligation to protect nor serve citizens and why early cops were also strike breakers.

While the origins of an institution don't necessarily dictate how it is structured and operated hundreds of years later, they do give insight into how the institution was designed and what purposes/roles it was actually filling. Today, thanks to various forms of "copaganda" in media, there's rhetoric that people should support and appreciate the police, that they are fair and effective and protect us from crime and villainy. As we'll continue to describe, I think the police are much more similar to their roots than the fiction they're portrayed as.

Discriminating against the poor

The police are designed to reinforce the capitalist status quo; the "law and order" they uphold is less so to do with ensuring life is fair and safe for all, but rather to keep the working class in check so the capitalist class are safe and secure. This is most evident by looking at how many laws primarily affect the poor and how rarely laws are enforced when the perpetrator is a capitalist.

"The law, in its majestic equality, forbids rich and poor alike to sleep under bridges, to beg in the streets, and to steal their bread."
Anatole France

Property crime lead to over 750,000 arrests in 2019. Wage theft, which according to a 2014 study may account for up to $50 Billion stolen, is a civil matter that doesn't lead to any arrests. In fact, white collar misdeeds are often not classified as criminal offenses - that's why after the 2008 housing market crash that devastated millions, only 1 banker was arrested and it was for something relatively trivial compared to the actual crash.

Even when it is a criminal offense, white collar crime is rarely punished. A lot of societal elites get away with horrendous misdeeds essentially out in the open. In fact, prosecuting the rich is so out of the norm that a rookie cop arresting Justin Timberlake caused a kerfuffle online because of just how much people like Justin aren't supposed to get arrested.

As a side note, there's a double standard here where rich are treated differently from poor people when they're the perpetrator of the crime, but not when they're the victim. If you look online for opinions on whether stealing from the rich to give to the poor is actually justified, you'll get a fairly overwhelming response that "theft is theft" and the context within which the theft occurred is not relevant. I think it's important to keep in mind the context of how the rich have rigged the system to consolidate wealth in the hands of as few as possible, and the impact that has had on society. On other issues, people are just fine dealing with nuance, like how violence is justified when it's self defense. I believe our society has been deliberately shaped to have the value that the victim being poor vs rich shouldn't matter, specifically because it benefits the rich.

Racism

The PIC has not shaken off the racism ingrained within its roots. Arrests are not proportional to actual crime rates, disproportionately affecting people of color - including when the cops themselves are black. Additionally, laws have been introduced throughout the history of the US that were explicitly designed to affect minorities, like the Jim Crow laws or the entirety of Nixon's war on drugs (a victimless "crime").

The police are an active threat to black people, who are 3x as likely to be shot and killed from the police without presenting a threat. That makes cops people to be avoided and who cannot be relied upon in an emergency. Even calling the police yourself is a risk.

Cost

The government spends hundreds of billions of dollars on the incarceral system, an absolutely profound amount of money that could make enormous differences had it been put to social services instead.

The prison system has for profit private prisons with minimum occupancy clauses that cost taxpayers money if we don't arrest enough people. This is a gross financial incentive to arrest more people, and it disincentivizes actual rehabilitation. These contribute to the US' incredibly high recidivism rates.

Ineffectiveness at stopping crime

Most crimes performed are out of necessity, not malice. For example, few would be stealing baby formula or bread if it weren't for our economic system introducing artificial scarcity to keep prices going up.

America has the highest incarceration rate in the world, for a variety of the reasons mentioned in this document. Yet, the fear of punishment and imprisonment does not seem to have the effect of discouraging crime. Indeed, increasing incarceration does not decrease crime.

Criminal officers

Officers themselves perpetrate a lot of crime (and I suspect there's a lot of police crimes that doesn't get reported), including 1/3 of all murders that involve a stranger, and are typically protected by a corrupt system with the strongest union in the nation (often attributed to the union serving the interests of capital, rather than workers like labor unions). In particular, officers have incredibly high rates of interspousal conflicts. Therefore, abolitionism is the only solution to gender-based violence.

How to abolish police

There are many ways to reduce the need of police until it's eventually zero. Immediately, perpetratore of victimless crimes should be let out of prison. You can also reduce most root causes of crime, rather than spending the money on incarcerating the perpetrators.

Crime reduction

Abolitionists still want to ensure public safety, just not through policing and incarceration. They believe, since most crime is not born of malice, that improving society by ensuring everyone's needs are met would evaporate the majority of crimes as well - at least as many as are prevented by the current system. Police are incredibly over funded, enough to buy things like surplus tanks from the US military. That money can instead go to social programs that would solve the root causes that lead to crimes.

Societies can and will find alternative ways of preventing any specific crime. An often used example is if you have a drunk friend who is about to drive home, you typically will help get them a ride (driving yourself if you're sober, or calling them a cab or uber otherwise) rather than calling the police on them. Abolitionism finds policing as only required by those who lack the political imagination to find other solutions - basically, cure the diseases rather than treat the symptoms. At a systemic level, drunk driving can be reduced or eliminated by improving public transit.

Dangerous incidents

With the police abolished, there are likely to still be cases where an individual is a danger to themselves or others. For these situations, there are ideas on how to resolve it without state sanctioned violence, that typically focus on local communities setting up alternative resources. Mobile crisis teams are one such alternative, although not without similar concerns regarding their authority to forcibly incarcerate people in mental health hospitals. There are a lot of alternatives out there, but they're typically specific to local communities and don't really have a "one size fits all" solution. Here's an article about a couple such initiatives, and this article linked earlier also discusses some specific local initiatives.

Another criticism of prison abolitionism specifically is What do you do with the murderers and rapists?, but as that article describes: we already don't incarcerate many murderers and rapists, especially the significant amount of murderers and rapists who are also officers. It argues the incarceral system already fails in this regard, and focuses on punishing the perpetrator rather than helping the victims, which is something we could do without incarceration.

Consequences

While punishments are not good deterrents, some consequences for crimes are still justified and can be enforced without requiring incarceration. A victim may be "made whole" (have the damage reversed to the best of our ability) at expense of the perpetrator, or the society itself (using resources its no longer spending on police or prison). If there's a material cause for the crime having taken place, e.g. a hungry person stealing food, those material conditions can be improved. For cases where the perpetrator is chronically exhibiting anti-social behavior, a trip to a rehabilitation facility, which would be operated significantly differently from the PIC, could be warranted. Stuff like anger management courses or resources to help kick addictions would naturally still be present in a society without prisons.

Further reading

I have not finished reading it yet myself, but I recommend We Do This ‘Til We Free Us by Mariame Kaba based on this NBC article on the book and author.

How police make up the law by Philosophy Tube is a very well produced look at how police got their de facto supreme authority, and it's implications. They have several other videos on the police I recommend, and any other videos they've made 😃.

Abolition notes contains a lot of public documents and guides on prison abolition and related leftist causes.

+ \ No newline at end of file diff --git a/garden/political-quizzes/index.html b/garden/political-quizzes/index.html index 3df98f554..23aa75623 100644 --- a/garden/political-quizzes/index.html +++ b/garden/political-quizzes/index.html @@ -6,14 +6,14 @@ Political Quizzes | The Paper Pilot - + - + - - - + + + @@ -53,9 +53,9 @@ -
Skip to content

Political Quizzes

841 words, ~5 minute read. Planted -.


Political quizzes are a bit of a guilty pleasure of mine. I really enjoy getting my beliefs distilled into a handful of labels, and getting forced to think about issues I may not have thought about that thoroughly. I often take issue with the wording of various questions though, and certainly have opinions on some quizzes being better than others.

Ultimately, the reason I consider these quizzes a guilty pleasure is because the results shouldn't really be used for anything. I believe we should vote on the issues directly, and any form of Representative Democracy is an unnecessary abstraction. The labels may be useful as a mnemonic, but not as useful as the individual answers and the justifications behind those answers. Plus, people are going to interpret the questions differently, especially when it comes to understanding terms like liberalism, freedom, or merit.

With all that said, here I'll discuss some tests I've taken, the results I've gotten l, and my overall thoughts on it. I'll include the dates taken so they can map to My Political Journey.

Prism Political Quiz

Made by the six triangles creator, I really like this test! It actually might be my favorite. It novelly gives you multiple positions to take on a given issue, rather than a statement you can agree or disagree with. I overall really liked the choices, and nearly always felt one represented my views.

I like the results I got on 2024-09-06. I was surprised at my government value being just "direct democracy", when the way I define my views on Government in My Political Beliefs (at the time of taking the test), which I believe I reflected accurately in my responses here, would probably include at least some points on anarchism and confederationism. That said, I liked these results so much that they inspired me to write that page on my political beliefs, which takes clear inspiration from this test.

Six Triangles

I was intrigued by Six Triangles' idea of replacing axes with triangles, although some of the additional points seem a bit redundant, or just acted as a disguised additional axis. For example, the truth corner of personal freedom is not really related to the axis of freedom vs security. It could have easily been its own axis specific to misinformation. Similarly, I think the burden corner of equality is going to be highly correlated to their equality of opportunity score. Others, however, really benefit from the third point, like economy being split up into laissez faire capitalism, "well regulated" capitalism, and socialism.

Unfortunately, I found a lot of the questions to be poorly worded or vague. For example, I disagree with the statement "The government occasionally needs to do things which aren't popular for the good of its people" because popular isn't sufficient, but in a system that requires unanimity (or near unanimity), I'd argue everything that gets passed is for the good of the people, based off the values and considerations of those specific people. That nuance doesn't carry over if I just select "disagree" though. They also have the statement "Small government is usually better than big government" without any context for what big vs small mean in this context: number of employees? Amount of nationalized services? Number of constituents? Amount of regulations? This distinction matters for getting (more) accurate results.

The results from taking it on 2024-09-05 were quite satisfying to go through. I particularly enjoyed being called a "Fanatic anti-imperialist". The main score I disagreed with was the government triangle; I would've preferred a higher minarchy score.

SapplyValues

I took the SapplyValues quiz on 2024-05-07:

4Orbs

I took the 4Orbs quiz on 2023-07-09:

Spekr

I like that this quiz gives live feedback, as it helped me introspect on the differences between my self-reported positions versus positions political quizzes assign me (for example, I usually think I'm way closer to anarchist than these tests usually put me, although funnily enough this quiz probably gave me one of the strongest anarchist score of any test I've taken). I also like that the creator is an anarchist themselves, which is likely uncommon across political quiz writers. I also felt like a lot of the questions were phrased in quite interesting ways.

I took the spekr quiz on 2023-05-17:

isidewith

I really didn't like this quiz. I think its overly-constrained to the range of discussion considered politically viable in America, and therefore didn't ask any questions about abolishing the state or replacing corporations with worker's co-operatives. I disagree with my results here moreso than any other political quiz I've taken.

I took the isidewith quiz on 2023-05-03:

I got quite different results on 2016-10-30, pre-radicalization:

Political compass

I took the political compass quiz on 2023-02-19:

I'd gotten similar results on 2022-06-15:

9Axes

I only took the short version, but here are my results from taking the 9Axes quiz on 2022-06-15:

- +
Skip to content

Political Quizzes

841 words, ~5 minute read. Planted +.


Political quizzes are a bit of a guilty pleasure of mine. I really enjoy getting my beliefs distilled into a handful of labels, and getting forced to think about issues I may not have thought about that thoroughly. I often take issue with the wording of various questions though, and certainly have opinions on some quizzes being better than others.

Ultimately, the reason I consider these quizzes a guilty pleasure is because the results shouldn't really be used for anything. I believe we should vote on the issues directly, and any form of Representative Democracy is an unnecessary abstraction. The labels may be useful as a mnemonic, but not as useful as the individual answers and the justifications behind those answers. Plus, people are going to interpret the questions differently, especially when it comes to understanding terms like liberalism, freedom, or merit.

With all that said, here I'll discuss some tests I've taken, the results I've gotten l, and my overall thoughts on it. I'll include the dates taken so they can map to My Political Journey.

Prism Political Quiz

Made by the six triangles creator, I really like this test! It actually might be my favorite. It novelly gives you multiple positions to take on a given issue, rather than a statement you can agree or disagree with. I overall really liked the choices, and nearly always felt one represented my views.

I like the results I got on 2024-09-06. I was surprised at my government value being just "direct democracy", when the way I define my views on Government in My Political Beliefs (at the time of taking the test), which I believe I reflected accurately in my responses here, would probably include at least some points on anarchism and confederationism. That said, I liked these results so much that they inspired me to write that page on my political beliefs, which takes clear inspiration from this test.

Six Triangles

I was intrigued by Six Triangles' idea of replacing axes with triangles, although some of the additional points seem a bit redundant, or just acted as a disguised additional axis. For example, the truth corner of personal freedom is not really related to the axis of freedom vs security. It could have easily been its own axis specific to misinformation. Similarly, I think the burden corner of equality is going to be highly correlated to their equality of opportunity score. Others, however, really benefit from the third point, like economy being split up into laissez faire capitalism, "well regulated" capitalism, and socialism.

Unfortunately, I found a lot of the questions to be poorly worded or vague. For example, I disagree with the statement "The government occasionally needs to do things which aren't popular for the good of its people" because popular isn't sufficient, but in a system that requires unanimity (or near unanimity), I'd argue everything that gets passed is for the good of the people, based off the values and considerations of those specific people. That nuance doesn't carry over if I just select "disagree" though. They also have the statement "Small government is usually better than big government" without any context for what big vs small mean in this context: number of employees? Amount of nationalized services? Number of constituents? Amount of regulations? This distinction matters for getting (more) accurate results.

The results from taking it on 2024-09-05 were quite satisfying to go through. I particularly enjoyed being called a "Fanatic anti-imperialist". The main score I disagreed with was the government triangle; I would've preferred a higher minarchy score.

SapplyValues

I took the SapplyValues quiz on 2024-05-07:

4Orbs

I took the 4Orbs quiz on 2023-07-09:

Spekr

I like that this quiz gives live feedback, as it helped me introspect on the differences between my self-reported positions versus positions political quizzes assign me (for example, I usually think I'm way closer to anarchist than these tests usually put me, although funnily enough this quiz probably gave me one of the strongest anarchist score of any test I've taken). I also like that the creator is an anarchist themselves, which is likely uncommon across political quiz writers. I also felt like a lot of the questions were phrased in quite interesting ways.

I took the spekr quiz on 2023-05-17:

isidewith

I really didn't like this quiz. I think its overly-constrained to the range of discussion considered politically viable in America, and therefore didn't ask any questions about abolishing the state or replacing corporations with worker's co-operatives. I disagree with my results here moreso than any other political quiz I've taken.

I took the isidewith quiz on 2023-05-03:

I got quite different results on 2016-10-30, pre-radicalization:

Political compass

I took the political compass quiz on 2023-02-19:

I'd gotten similar results on 2022-06-15:

9Axes

I only took the short version, but here are my results from taking the 9Axes quiz on 2022-06-15:

+ \ No newline at end of file diff --git a/garden/pre-order-bonuses/index.html b/garden/pre-order-bonuses/index.html index 56f3a8829..5d6884d71 100644 --- a/garden/pre-order-bonuses/index.html +++ b/garden/pre-order-bonuses/index.html @@ -6,14 +6,14 @@ Pre-Order Bonuses | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Pre-Order Bonuses

98 words, ~1 minute read. Planted +

Skip to content

Pre-Order Bonuses

98 words, ~1 minute read. Planted . Last tended to -.


Referenced by:Video Game Monetization

Pre-order bonuses are benefits given to players who buy a game before it comes out

They primarily serve to benefit the company

  • People commit to buying before the embargo date passes
  • Heuristic of how well it'll sell after launch
  • Slight lead on return on investment
    • More significantly impacts indie studios, who will likely have less cash on hand
  • Companies make deals with storefronts to have exclusive bonuses, to drive customers to said storefronts

Common bonuses:

  • Digital goods:
  • Physical goods:
    • Typically pins, keychains, etc.
    • Typically only included in physical editions of the game
- +.


Referenced by:Video Game Monetization

Pre-order bonuses are benefits given to players who buy a game before it comes out

They primarily serve to benefit the company

  • People commit to buying before the embargo date passes
  • Heuristic of how well it'll sell after launch
  • Slight lead on return on investment
    • More significantly impacts indie studios, who will likely have less cash on hand
  • Companies make deals with storefronts to have exclusive bonuses, to drive customers to said storefronts

Common bonuses:

  • Digital goods:
  • Physical goods:
    • Typically pins, keychains, etc.
    • Typically only included in physical editions of the game
+ \ No newline at end of file diff --git a/garden/premium-currency/index.html b/garden/premium-currency/index.html index f5bdc57e6..f84069c0d 100644 --- a/garden/premium-currency/index.html +++ b/garden/premium-currency/index.html @@ -6,14 +6,14 @@ Premium Currency | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Premium Currency

71 words, ~0 minute read. Planted +

Skip to content

Premium Currency

71 words, ~0 minute read. Planted . Last tended to -.


Referenced by:Pre-Order Bonuses

A popular form of MTX where instead of receiving a useful item or effect directly, you receive a currency that is then spent on an in game store

Reasons companies use them

  • Abstracts the real world price of items
    • No strict conversion ratio
    • Discounts for bulk purchasing
    • Small amounts given for free based on story progression or watching ads
  • Consolidates smaller purchases into a larger one (decreasing friction of individual purchases)
- +.


Referenced by:Pre-Order Bonuses

A popular form of MTX where instead of receiving a useful item or effect directly, you receive a currency that is then spent on an in game store

Reasons companies use them

  • Abstracts the real world price of items
    • No strict conversion ratio
    • Discounts for bulk purchasing
    • Small amounts given for free based on story progression or watching ads
  • Consolidates smaller purchases into a larger one (decreasing friction of individual purchases)
+ \ No newline at end of file diff --git a/garden/prescriptivism-vs-descriptivism/index.html b/garden/prescriptivism-vs-descriptivism/index.html index 40c442d28..d8b0cc56d 100644 --- a/garden/prescriptivism-vs-descriptivism/index.html +++ b/garden/prescriptivism-vs-descriptivism/index.html @@ -6,14 +6,14 @@ Prescriptivism vs Descriptivism | The Paper Pilot - + - + - - - + + + @@ -53,9 +53,9 @@ -
Skip to content

Prescriptivism vs Descriptivism

256 words, ~1 minute read. Planted -.


Referenced by:Social Constructs

These two terms refer to how words are defined. Prescriptivism is where definitions are written by an authority of some sort and users of the language are supposed to respect that definition, or else they are incorrect. Prescriptivism defines a truth, a boundary on what is allowed. Descriptivism, on the other hand, argues definitions should be based on how the word is currently being used. Someone using it differently is not wrong, they're just part of the normal process through which definitions can change. Descriptivism, therefore, does not define an objective truth. A notable example of this dichotomy is the definition of "literally". It was defined as meaning something that is to be taken at face value, but dictionaries have found justification for it having a second, near opposite, definition.

I'm fairly against prescriptivism, but acknowledge the argument that words are more useful when their definitions don't change underneath you, especially in cases where the word can now ambiguously refer to the opposite of one of its other definitions. However, the cultural change in definitions happens regardless, so I think it's important to be able to analyze how words are being used and decide if and when it makes sense to update those definitions. I feel the same way about all Social Constructs , which language is just one of.

Dictionaries take a stance in between the two extremes - both becoming an authoritative (and therefore prescriptive) source of definitions, but updating them as deemed necessary to more closely match their real-world uses.

- +
Skip to content

Prescriptivism vs Descriptivism

256 words, ~1 minute read. Planted +.


Referenced by:Social Constructs

These two terms refer to how words are defined. Prescriptivism is where definitions are written by an authority of some sort and users of the language are supposed to respect that definition, or else they are incorrect. Prescriptivism defines a truth, a boundary on what is allowed. Descriptivism, on the other hand, argues definitions should be based on how the word is currently being used. Someone using it differently is not wrong, they're just part of the normal process through which definitions can change. Descriptivism, therefore, does not define an objective truth. A notable example of this dichotomy is the definition of "literally". It was defined as meaning something that is to be taken at face value, but dictionaries have found justification for it having a second, near opposite, definition.

I'm fairly against prescriptivism, but acknowledge the argument that words are more useful when their definitions don't change underneath you, especially in cases where the word can now ambiguously refer to the opposite of one of its other definitions. However, the cultural change in definitions happens regardless, so I think it's important to be able to analyze how words are being used and decide if and when it makes sense to update those definitions. I feel the same way about all Social Constructs , which language is just one of.

Dictionaries take a stance in between the two extremes - both becoming an authoritative (and therefore prescriptive) source of definitions, but updating them as deemed necessary to more closely match their real-world uses.

+ \ No newline at end of file diff --git a/garden/profectus/index.html b/garden/profectus/index.html index 864210c30..cc7330b87 100644 --- a/garden/profectus/index.html +++ b/garden/profectus/index.html @@ -6,14 +6,14 @@ Profectus | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Profectus

27 words, ~0 minute read. Planted +

Skip to content

Profectus

27 words, ~0 minute read. Planted . Last tended to -.


Referenced by:Advent IncrementalPlanar Pioneers
Tagged by:Advent IncrementalKronosPlanar Pioneers
Tags:My Projects

Profectus is an Open Source game engine I made, loosely based on The Modding Tree by Acamaeda. It centers around using Vue's reactivity and is designed with the intent to not restrain developers into making games that only look or behave "one way". Also, technically it's more of a template (rather than engine) for making web games.

Games made with Profectus:

  • Everything in this garden tagged with this page!
  • The entries to the Profectus Creation Jam
  • Primordia by Jacorb
- +.


Referenced by:Advent IncrementalPlanar Pioneers
Tagged by:Advent IncrementalKronosPlanar Pioneers
Tags:My Projects

Profectus is an Open Source game engine I made, loosely based on The Modding Tree by Acamaeda. It centers around using Vue's reactivity and is designed with the intent to not restrain developers into making games that only look or behave "one way". Also, technically it's more of a template (rather than engine) for making web games.

Games made with Profectus:

  • Everything in this garden tagged with this page!
  • The entries to the Profectus Creation Jam
  • Primordia by Jacorb
+ \ No newline at end of file diff --git a/garden/representative-democracy/index.html b/garden/representative-democracy/index.html index e9a9b04db..9295ca8a4 100644 --- a/garden/representative-democracy/index.html +++ b/garden/representative-democracy/index.html @@ -6,14 +6,14 @@ Representative Democracy | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Representative Democracy

87 words, ~0 minute read. Planted +

Skip to content

Representative Democracy

87 words, ~0 minute read. Planted . Last tended to -.


Referenced by:AnarchismPolitical Quizzes

A form of democracy where people vote for representatives who then vote on the actual issues. The US has a representative democracy. By virtue of representatives not perfectly reflecting the views of their constituents, and by forming a hierarchy of power, this is a form of Democracy that is not Anarchistic.

Representative forms of government were once useful for their logistical simplifications, but now primarily serve as a way to limit the range of acceptable political opinions/options and to perpetuate the reign of those in power.

- +.


Referenced by:AnarchismPolitical Quizzes

A form of democracy where people vote for representatives who then vote on the actual issues. The US has a representative democracy. By virtue of representatives not perfectly reflecting the views of their constituents, and by forming a hierarchy of power, this is a form of Democracy that is not Anarchistic.

Representative forms of government were once useful for their logistical simplifications, but now primarily serve as a way to limit the range of acceptable political opinions/options and to perpetuate the reign of those in power.

+ \ No newline at end of file diff --git a/garden/scientific-constructivism/index.html b/garden/scientific-constructivism/index.html index 1c061d718..46eb62411 100644 --- a/garden/scientific-constructivism/index.html +++ b/garden/scientific-constructivism/index.html @@ -6,14 +6,14 @@ Scientific Constructivism | The Paper Pilot - + - + - - - + + + @@ -53,9 +53,9 @@ -
Skip to content

Scientific Constructivism

271 words, ~1 minute read. Planted -.


Scientific constructivism is the philosophical idea that science is a Social Construct , in this case one created socially by scientists.

In her video on Social Constructs, Philosophy Tube discusses taxonomy as an example social construct. We observe animals' natural properties and form categories along arbitrary lines, and just deal with weird edge cases like the platypus that don't neatly fit into our prescribed lines. Some criticized this argument, because modern taxonomy typically looks at lineage and nearest shared ancestors, which avoids those edge cases and is therefore seen as a more "objective" measure. But us choosing to taxonomize using that metric versus any other is still inherently arbitrary and thus a construct.

This lovely response to Richard Dawkins claiming science is not a social construct is a great read. It argues, amongst other points, that science is to natural properties as a map is to the physical landscape. That is, science and maps are social constructs because they are our attempts to define and understand the underlying properties. Science is a process, not objective truth. (This same argument could be applied to mathematics, where there is some underlying property we don't have a name for, but mathematics - the axioms, theorems, proofs, etc. - as a collective body is a social construct above that underlying property). Philosophy Tube describes how height, one such natural property, might be used at different layers of social constructs. We have a concept of "tallness", which is a social construct based on the underlying property "height". However there could be a society that goes an extra layer of abstraction up and has a concept of "bigs", which are the elites of this society, as determined by their exceptional tallness. We might think its silly of such a society to structure themselves in this way, and question their reasoning for having a concept of "bigs" in the first place. But so to could a society that's one layer below ours question us for having a concept of "tallness", arguing that its fine to measure height but that its silly to describe people as being tall or not. They might argue that they, by merely measuring a natural property of height, do not have a social construct. However a layer below even them might question them for choosing to measure height in the first place. Does that not inherently imbue meaning (and therefore a social definition) upon the measured number? And by that logic, any measured property, by us choosing to measure it in the first place, is some level of social construct.

Science will often be affected by our own biases and come to incorrect conclusions. A classic example of this is phrenology, a racist "science" that used its supposed " Objectivity" to argue for racial differences that didn't exist. You may argue that science has already built in affordances for previous research being determined incorrect, however. We have (flawed) peer reviews and regularly (ish) replicate experiments and further verify various historical theories. However even the process of peer reviews, the scientific method, and conducting science at all are social constructs. Academia similarly has arbitrary restrictions, like defining statistical significance at 5% difference, that arbitrarily determine what is science and what is not (and often leads to data dredging).

While looking online to see people who agree and disagree with science as a social construct, I found some interesting pages that didn't really fit in elsewhere. I found this paper, Questioning science: how knowledge is socially constructed , which has a cool sounding abstract but I haven't found the article itself, and considering how little its been cited it seems far from seminal. I also found this entertaining forum thread discussing social constructs and science, which became a good example of how many people believe something being a construct means its not "real", and that therefore anything real/observable must therefore not be a construct. Fortunately, there are some voices in there attempting to clarify the nature of social constructs, and the back and forth was just enjoyable to read.

- +
Skip to content

Scientific Constructivism

271 words, ~1 minute read. Planted +.


Scientific constructivism is the philosophical idea that science is a Social Construct , in this case one created socially by scientists.

In her video on Social Constructs, Philosophy Tube discusses taxonomy as an example social construct. We observe animals' natural properties and form categories along arbitrary lines, and just deal with weird edge cases like the platypus that don't neatly fit into our prescribed lines. Some criticized this argument, because modern taxonomy typically looks at lineage and nearest shared ancestors, which avoids those edge cases and is therefore seen as a more "objective" measure. But us choosing to taxonomize using that metric versus any other is still inherently arbitrary and thus a construct.

This lovely response to Richard Dawkins claiming science is not a social construct is a great read. It argues, amongst other points, that science is to natural properties as a map is to the physical landscape. That is, science and maps are social constructs because they are our attempts to define and understand the underlying properties. Science is a process, not objective truth. (This same argument could be applied to mathematics, where there is some underlying property we don't have a name for, but mathematics - the axioms, theorems, proofs, etc. - as a collective body is a social construct above that underlying property). Philosophy Tube describes how height, one such natural property, might be used at different layers of social constructs. We have a concept of "tallness", which is a social construct based on the underlying property "height". However there could be a society that goes an extra layer of abstraction up and has a concept of "bigs", which are the elites of this society, as determined by their exceptional tallness. We might think its silly of such a society to structure themselves in this way, and question their reasoning for having a concept of "bigs" in the first place. But so to could a society that's one layer below ours question us for having a concept of "tallness", arguing that its fine to measure height but that its silly to describe people as being tall or not. They might argue that they, by merely measuring a natural property of height, do not have a social construct. However a layer below even them might question them for choosing to measure height in the first place. Does that not inherently imbue meaning (and therefore a social definition) upon the measured number? And by that logic, any measured property, by us choosing to measure it in the first place, is some level of social construct.

Science will often be affected by our own biases and come to incorrect conclusions. A classic example of this is phrenology, a racist "science" that used its supposed " Objectivity" to argue for racial differences that didn't exist. You may argue that science has already built in affordances for previous research being determined incorrect, however. We have (flawed) peer reviews and regularly (ish) replicate experiments and further verify various historical theories. However even the process of peer reviews, the scientific method, and conducting science at all are social constructs. Academia similarly has arbitrary restrictions, like defining statistical significance at 5% difference, that arbitrarily determine what is science and what is not (and often leads to data dredging).

While looking online to see people who agree and disagree with science as a social construct, I found some interesting pages that didn't really fit in elsewhere. I found this paper, Questioning science: how knowledge is socially constructed , which has a cool sounding abstract but I haven't found the article itself, and considering how little its been cited it seems far from seminal. I also found this entertaining forum thread discussing social constructs and science, which became a good example of how many people believe something being a construct means its not "real", and that therefore anything real/observable must therefore not be a construct. Fortunately, there are some voices in there attempting to clarify the nature of social constructs, and the back and forth was just enjoyable to read.

+ \ No newline at end of file diff --git a/garden/social-constructs/index.html b/garden/social-constructs/index.html index 26725a28b..4d3fd0216 100644 --- a/garden/social-constructs/index.html +++ b/garden/social-constructs/index.html @@ -6,14 +6,14 @@ Social Constructs | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Social Constructs

1088 words, ~6 minute read. Planted +

Skip to content

Social Constructs

1088 words, ~6 minute read. Planted . Last tended to -.


Referenced by:AnarchismGenderGerrymanderingGuide to Incrementals/Defining the GenreObjectivityPrescriptivism vs DescriptivismScientific ConstructivismTrans athletes in sports

Social constructs are concepts with social definitions. Having a "social definition" really just means its some concept or property some group of peoples (or even animals) has prescribed meaning to. You know of and use these all the time throughout your life, and have likely identified some common ones like gender or class. As we'll discuss, however, there are far, far many more social constructs than the ones commonly referred to as such. It should be noted that while these concepts are essentially "made up", in the sense that they are arbitrary distinctions created by imperfect beings, that does not make them "not real". They exist and are typically created for a reason, often convenience. However, those reasons can be analyzed and determined to be more harmful than useful. This article's goal is to discuss and encourage analyzing social constructs, to better identify them and determine their utility and impact on society. Furthermore that it's possible to change or even destroy these constructs, and it's our social duty to do so when appropriate.

With a definition for social constructs as a concept established, how would you go about defining a specific social construct? Well that's tricky, due to social constructs' nature. It's useful to define words using either Prescriptivism or Descriptivism, but social constructs are much too ephemeral and complex to truly be defined using either approach. How would you attempt to make a complete, non-simplified definition of gender, for example? Gender has an impact on all parts of society, with gender roles shaping our entire lives and society and it interacts with various other similarly complicated constructs like class or family. All of this makes these concepts so complex that many incredibly smart people will spend their entire lives just writing about a single construct. While useful, these papers are obviously not the way we are typically introduced to constructs, or how we gain an understanding of them within a complex network of constructs.

Kids effectively "learn" the definitions of social constructs via exposure to them. They don't need to be explicitly outlined, at least not wholly, but rather experienced and lived. Kids observe people performing their gender roles, recognize their family and duties within it, calculate their age by counting the number of birthdays they've had, etc. Humans are powerful at recognizing patterns and through that naturally build an understanding, piece by piece, for all these constructs and how they interact, even if they couldn't formally define any of them. They'll go on to follow the unstated rules of these constructs, reinforcing them and teaching them by demonstration to following generations.

These constructs form a complex web, where any specific construct is only useful in the context of the web it is both a part of and dependent on. For example, knowing what a "bakery" is depends on the concept of a store, which depends on the concept of a building, and which depends on the concept of a structure. And this is just one path we could've taken - we could've alternatively explored bread or employees or shopping, and so on.

Ultimately, constructs are supposed to be useful. They allow us to communicate, understand, and exist within our society. One without any constructs would be impossible to do anything in. But these constructs also gained a lot of meanings during times of oppressive forces taking over the world, and can seriously harm people, particularly with concepts like Gender. In the same way these constructs allow us to understand the world around us, they can also mold us to fit those definitions. That's my real motive behind this page - to help recognize these constructs, analyze their utility, and ultimately decide if they're a construct worth continued support.

Some social constructs may seem to have straightforward definitions, but there is nuance and caveats that are still exclusively defined through social means. Take soup, for example. Oxford describes it as "a liquid dish, typically made by boiling meat, fish, or vegetables, etc. in stock or water". Well first off, that "typically" is already a concession that there are some traits that seem common, but not necessary to the definition. Is a bowl of cereal and milk considered soup? How liquid does the base have to be - would spaghetti Os count? And perhaps even a "liquid dish" is a murky requirement itself; let's talk about a game called Something something soup something, which uses gameplay of deciding which of various weird maybe-soups actually counts as soup. Their goal is to reveal through gameplay that "that even an ordinary concept like 'soup' is vague, shifting, impossible to define exhaustively". They released an analysis of results from what people typically considered requirements for "soupyness", and found nearly a third of participants (from focus groups and tracked players) accepted solids like rocks or ice cubes as viable bases for a soup. The oxford definition didn't mention container or utensil used for consuming soup, but the game found 25% of their focus group and 10% of their players considered the container being bowl-like or the utensil spoon-like as important. The point is that these definitions are subjective and learned socially, and thus have blurred edges that can change over time - you won't be able to find a complete definition in any dictionary. And don't even get me started on what a sandwich is!

Similar to how social constructs can have a nice simple definition that doesn't really encapsulate the social definition, the definition of social constructs as "concepts with social definitions" doesn't really explain just how ubiquitous these concepts are . Nearly everything is a social construct; everything from "age" to "bakeries" to "north" to "sandwiches" are social constructs; These concepts that society has built an understanding of over long periods of time, and have been shaped by our shared cultures and values. Even naming those constructs was a social agreement that those concepts are worth pointing out - Why make distinctions between different types of stores? Why distinguish some buildings as stores in the first place? Or call some structures buildings and others, like a fence, not? All of these are social constructs we use to help understand the world, that we learned through our experiences within our given society and culture. They're also all arbitrary and oftentimes you'll see these lines and distinctions differ between peoples. Take color, for example: We have many different colors - red, blue, green, yellow, purple, and so on. But why do we have those specific colors? Why does light red get its own name but not light green? Why is blue a boy color and pink a girl color? Is the dress black and blue or white and gold? Where is the line between dark blue and black? Why does the rainbow only sometimes include an indigo and violet? Well, all these decisions just kinda resolve as society continues to change. Those categories of colors just happened to be the ones our culture uses. But other cultures separate them out in different ways, like caring more about brightness than hue. Some cultures don't even have a concept of color, or might group colors differently than us - like grouping some colors as "like ripe fruit", which may seem just as out of place to us as us grouping green and tan in a category called "camo" would seem out of place to them.

- +.


Referenced by:AnarchismGenderGerrymanderingGuide to Incrementals/Defining the GenreObjectivityPrescriptivism vs DescriptivismScientific ConstructivismTrans athletes in sports

Social constructs are concepts with social definitions. Having a "social definition" really just means its some concept or property some group of peoples (or even animals) has prescribed meaning to. You know of and use these all the time throughout your life, and have likely identified some common ones like gender or class. As we'll discuss, however, there are far, far many more social constructs than the ones commonly referred to as such. It should be noted that while these concepts are essentially "made up", in the sense that they are arbitrary distinctions created by imperfect beings, that does not make them "not real". They exist and are typically created for a reason, often convenience. However, those reasons can be analyzed and determined to be more harmful than useful. This article's goal is to discuss and encourage analyzing social constructs, to better identify them and determine their utility and impact on society. Furthermore that it's possible to change or even destroy these constructs, and it's our social duty to do so when appropriate.

With a definition for social constructs as a concept established, how would you go about defining a specific social construct? Well that's tricky, due to social constructs' nature. It's useful to define words using either Prescriptivism or Descriptivism, but social constructs are much too ephemeral and complex to truly be defined using either approach. How would you attempt to make a complete, non-simplified definition of gender, for example? Gender has an impact on all parts of society, with gender roles shaping our entire lives and society and it interacts with various other similarly complicated constructs like class or family. All of this makes these concepts so complex that many incredibly smart people will spend their entire lives just writing about a single construct. While useful, these papers are obviously not the way we are typically introduced to constructs, or how we gain an understanding of them within a complex network of constructs.

Kids effectively "learn" the definitions of social constructs via exposure to them. They don't need to be explicitly outlined, at least not wholly, but rather experienced and lived. Kids observe people performing their gender roles, recognize their family and duties within it, calculate their age by counting the number of birthdays they've had, etc. Humans are powerful at recognizing patterns and through that naturally build an understanding, piece by piece, for all these constructs and how they interact, even if they couldn't formally define any of them. They'll go on to follow the unstated rules of these constructs, reinforcing them and teaching them by demonstration to following generations.

These constructs form a complex web, where any specific construct is only useful in the context of the web it is both a part of and dependent on. For example, knowing what a "bakery" is depends on the concept of a store, which depends on the concept of a building, and which depends on the concept of a structure. And this is just one path we could've taken - we could've alternatively explored bread or employees or shopping, and so on.

Ultimately, constructs are supposed to be useful. They allow us to communicate, understand, and exist within our society. One without any constructs would be impossible to do anything in. But these constructs also gained a lot of meanings during times of oppressive forces taking over the world, and can seriously harm people, particularly with concepts like Gender. In the same way these constructs allow us to understand the world around us, they can also mold us to fit those definitions. That's my real motive behind this page - to help recognize these constructs, analyze their utility, and ultimately decide if they're a construct worth continued support.

Some social constructs may seem to have straightforward definitions, but there is nuance and caveats that are still exclusively defined through social means. Take soup, for example. Oxford describes it as "a liquid dish, typically made by boiling meat, fish, or vegetables, etc. in stock or water". Well first off, that "typically" is already a concession that there are some traits that seem common, but not necessary to the definition. Is a bowl of cereal and milk considered soup? How liquid does the base have to be - would spaghetti Os count? And perhaps even a "liquid dish" is a murky requirement itself; let's talk about a game called Something something soup something, which uses gameplay of deciding which of various weird maybe-soups actually counts as soup. Their goal is to reveal through gameplay that "that even an ordinary concept like 'soup' is vague, shifting, impossible to define exhaustively". They released an analysis of results from what people typically considered requirements for "soupyness", and found nearly a third of participants (from focus groups and tracked players) accepted solids like rocks or ice cubes as viable bases for a soup. The oxford definition didn't mention container or utensil used for consuming soup, but the game found 25% of their focus group and 10% of their players considered the container being bowl-like or the utensil spoon-like as important. The point is that these definitions are subjective and learned socially, and thus have blurred edges that can change over time - you won't be able to find a complete definition in any dictionary. And don't even get me started on what a sandwich is!

Similar to how social constructs can have a nice simple definition that doesn't really encapsulate the social definition, the definition of social constructs as "concepts with social definitions" doesn't really explain just how ubiquitous these concepts are . Nearly everything is a social construct; everything from "age" to "bakeries" to "north" to "sandwiches" are social constructs; These concepts that society has built an understanding of over long periods of time, and have been shaped by our shared cultures and values. Even naming those constructs was a social agreement that those concepts are worth pointing out - Why make distinctions between different types of stores? Why distinguish some buildings as stores in the first place? Or call some structures buildings and others, like a fence, not? All of these are social constructs we use to help understand the world, that we learned through our experiences within our given society and culture. They're also all arbitrary and oftentimes you'll see these lines and distinctions differ between peoples. Take color, for example: We have many different colors - red, blue, green, yellow, purple, and so on. But why do we have those specific colors? Why does light red get its own name but not light green? Why is blue a boy color and pink a girl color? Is the dress black and blue or white and gold? Where is the line between dark blue and black? Why does the rainbow only sometimes include an indigo and violet? Well, all these decisions just kinda resolve as society continues to change. Those categories of colors just happened to be the ones our culture uses. But other cultures separate them out in different ways, like caring more about brightness than hue. Some cultures don't even have a concept of color, or might group colors differently than us - like grouping some colors as "like ripe fruit", which may seem just as out of place to us as us grouping green and tan in a category called "camo" would seem out of place to them.

+ \ No newline at end of file diff --git a/garden/social-media/index.html b/garden/social-media/index.html index 83a43858a..247ff8271 100644 --- a/garden/social-media/index.html +++ b/garden/social-media/index.html @@ -6,14 +6,14 @@ Social Media | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Social Media

222 words, ~1 minute read. Planted +

Skip to content

Social Media

222 words, ~1 minute read. Planted . Last tended to -.


Referenced by:CommuneDecentralized ModerationDecentralized Social MediaDigital LocalityFediverseFilter BubblesModeration

Social media is how we interact with people online. It's also increasingly becoming how we discover and discuss news and ideas. It's incredibly important, but flawed. A lot of pages in this digital garden criticize and attempt to solve these flaws.

Traditional social media is centralized, meaning you have to trust the central authority to be acting in your best interests. It also means you likely won't have control over the moderation rules, sorting methods, filters, or other aspects of the platform. Traditional social media is also overrun by entities trying to accumulate wealth in the "attention economy", meaning feeds are littered with influencers, advertisers, and scams. It's not a safe place to be and its not conducive to health conversations.

Federated Social Media is partially Decentralized, and includes services like Mastodon or Lemmy. These require self hosting, leading to it being a federation of smaller centralized authorities. Most people still won't have control over the platform, but may find a platform that's more tolerable to them. However, the process of doing so greatly increases the barrier of entry into the network, and stifles their adoption.

I personally advocate for a full decentralized social media, called the Agentic Fediverse . It should give full agency to the individual, and perhaps even introduce the concept of Digital Locality.

- +.


Referenced by:CommuneDecentralized ModerationDecentralized Social MediaDigital LocalityFediverseFilter BubblesModeration

Social media is how we interact with people online. It's also increasingly becoming how we discover and discuss news and ideas. It's incredibly important, but flawed. A lot of pages in this digital garden criticize and attempt to solve these flaws.

Traditional social media is centralized, meaning you have to trust the central authority to be acting in your best interests. It also means you likely won't have control over the moderation rules, sorting methods, filters, or other aspects of the platform. Traditional social media is also overrun by entities trying to accumulate wealth in the "attention economy", meaning feeds are littered with influencers, advertisers, and scams. It's not a safe place to be and its not conducive to health conversations.

Federated Social Media is partially Decentralized, and includes services like Mastodon or Lemmy. These require self hosting, leading to it being a federation of smaller centralized authorities. Most people still won't have control over the platform, but may find a platform that's more tolerable to them. However, the process of doing so greatly increases the barrier of entry into the network, and stifles their adoption.

I personally advocate for a full decentralized social media, called the Agentic Fediverse . It should give full agency to the individual, and perhaps even introduce the concept of Digital Locality.

+ \ No newline at end of file diff --git a/garden/synapse/index.html b/garden/synapse/index.html index 0f8c56182..9d11df4fa 100644 --- a/garden/synapse/index.html +++ b/garden/synapse/index.html @@ -6,14 +6,14 @@ Synapse | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Synapse

2 words, ~0 minute read. Planted +

Skip to content

Synapse

2 words, ~0 minute read. Planted . Last tended to -.


Referenced by:Incremental Social

Synapse is an Open Source server software for the Matrix protocol

- +.


Referenced by:Incremental Social

Synapse is an Open Source server software for the Matrix protocol

+ \ No newline at end of file diff --git a/garden/technocracy/index.html b/garden/technocracy/index.html index 8f5bccbf0..5160817c3 100644 --- a/garden/technocracy/index.html +++ b/garden/technocracy/index.html @@ -6,14 +6,14 @@ Technocracy | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Technocracy

296 words, ~2 minute read. Planted +

Skip to content

Technocracy

296 words, ~2 minute read. Planted . Last tended to -.


Technocracies are a form of government where technical experts make the decisions. It sounds appealing and like a solution to the "problem" of "How can Democracy be good if most people are stupid?". Well I don't think that's really a problem in the first place, as it implies some sort of objective knowledge and truth, when really the best decision is the one those affected by the decision most agree with. However, even under the premise that tyranny of the majority is a problem worth addressing, technocracies don't hold up under critical analysis.

Who decides the criteria for technical expertise? Whatever the answer is will be introducing bias into the government, because true meritocracies are a Neoliberal myth. Indeed, this government would likely just perpetuate people's existing material conditions, as those with power will have access to more resources, which means they'll be more likely to be able to meet the qualifications of technical expertise and thus remain in power. Conversely, those in poorer material conditions will be less likely to become technical experts, and thus have less agency to improve their material conditions.

In TikTok Vs Democracy, Abigail Thorne discusses how surveillance capitalism can lead to a technocracy-flavored version of authoritarianism, and argues that even if democracy is "not a system for choosing the best leader or guaranteeing the best outcome" that it is "a system that has maximal respect for everyone's equal humanity".

A similar implementation that's considered slightly more palatable is a democracy where those with more education get more votes. But this still has the same issues of who writes the criteria and perpetuating material conditions. That is, it makes the idea sound more palatable without meaningfully addressing any of the criticisms of technocracies.

- +.


Technocracies are a form of government where technical experts make the decisions. It sounds appealing and like a solution to the "problem" of "How can Democracy be good if most people are stupid?". Well I don't think that's really a problem in the first place, as it implies some sort of objective knowledge and truth, when really the best decision is the one those affected by the decision most agree with. However, even under the premise that tyranny of the majority is a problem worth addressing, technocracies don't hold up under critical analysis.

Who decides the criteria for technical expertise? Whatever the answer is will be introducing bias into the government, because true meritocracies are a Neoliberal myth. Indeed, this government would likely just perpetuate people's existing material conditions, as those with power will have access to more resources, which means they'll be more likely to be able to meet the qualifications of technical expertise and thus remain in power. Conversely, those in poorer material conditions will be less likely to become technical experts, and thus have less agency to improve their material conditions.

In TikTok Vs Democracy, Abigail Thorne discusses how surveillance capitalism can lead to a technocracy-flavored version of authoritarianism, and argues that even if democracy is "not a system for choosing the best leader or guaranteeing the best outcome" that it is "a system that has maximal respect for everyone's equal humanity".

A similar implementation that's considered slightly more palatable is a democracy where those with more education get more votes. But this still has the same issues of who writes the criteria and perpetuating material conditions. That is, it makes the idea sound more palatable without meaningfully addressing any of the criticisms of technocracies.

+ \ No newline at end of file diff --git a/garden/the-beginner-s-guide/index.html b/garden/the-beginner-s-guide/index.html index 7ec66dac2..b9650da19 100644 --- a/garden/the-beginner-s-guide/index.html +++ b/garden/the-beginner-s-guide/index.html @@ -6,14 +6,14 @@ The Beginner's Guide | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

The Beginner's Guide

144 words, ~1 minute read. Planted +

Skip to content

The Beginner's Guide

144 words, ~1 minute read. Planted . Last tended to -.


Referenced by:Davey Wreden
Tags:Davey Wreden

My favorite video game of all time, bar none. Created by Davey Wreden

The game broadly comments on the relationship between creators and consumers, and it can apply to all forms of art

  • Perhaps also an important commentary on parasocial relationships

Important analyses:

- +.


Referenced by:Davey Wreden
Tags:Davey Wreden

My favorite video game of all time, bar none. Created by Davey Wreden

The game broadly comments on the relationship between creators and consumers, and it can apply to all forms of art

  • Perhaps also an important commentary on parasocial relationships

Important analyses:

+ \ No newline at end of file diff --git a/garden/the-cozy-web/index.html b/garden/the-cozy-web/index.html index 112b1f7f0..8cc18c5e0 100644 --- a/garden/the-cozy-web/index.html +++ b/garden/the-cozy-web/index.html @@ -6,14 +6,14 @@ The Cozy Web | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

The Cozy Web

45 words, ~0 minute read. Planted +

Skip to content

The Cozy Web

45 words, ~0 minute read. Planted . Last tended to -.


Referenced by:Digital Gardens

The Cozy Web is an extension of the dark forest theory of the Internet

It refers to the part of the web that is not web indexable

This part of the web is known for not typically having ads or marketers

Popularized by this article written by Maggie Appleton, who has also written a lot about Digital Gardens

- +.


Referenced by:Digital Gardens

The Cozy Web is an extension of the dark forest theory of the Internet

It refers to the part of the web that is not web indexable

This part of the web is known for not typically having ads or marketers

Popularized by this article written by Maggie Appleton, who has also written a lot about Digital Gardens

+ \ No newline at end of file diff --git a/garden/the-indieweb/amplification/index.html b/garden/the-indieweb/amplification/index.html index 68bcd76eb..db71469ef 100644 --- a/garden/the-indieweb/amplification/index.html +++ b/garden/the-indieweb/amplification/index.html @@ -6,14 +6,14 @@ The IndieWeb/Amplification | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

The IndieWeb/Amplification

57 words, ~0 minute read. Planted +

Skip to content

The IndieWeb/Amplification

57 words, ~0 minute read. Planted . Last tended to -.


Referenced by:Incremental SocialKronos

Refers to reblogging (and re-hosting, sometimes) of someone else's content on your own site

The Internet is a series of webs discusses some ideas and best practices for amplification

To ensure the rehosted content actually came from the claimed author and was not tampered with, all content should be signed using The IndieWeb/Signature Blocks

- +.


Referenced by:Incremental SocialKronos

Refers to reblogging (and re-hosting, sometimes) of someone else's content on your own site

The Internet is a series of webs discusses some ideas and best practices for amplification

To ensure the rehosted content actually came from the claimed author and was not tampered with, all content should be signed using The IndieWeb/Signature Blocks

+ \ No newline at end of file diff --git a/garden/the-indieweb/signature-blocks/index.html b/garden/the-indieweb/signature-blocks/index.html index dc8d4dcca..9d7e6dec7 100644 --- a/garden/the-indieweb/signature-blocks/index.html +++ b/garden/the-indieweb/signature-blocks/index.html @@ -6,14 +6,14 @@ The IndieWeb/Signature Blocks | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

The IndieWeb/Signature Blocks

14 words, ~0 minute read. Planted +

Skip to content

The IndieWeb/Signature Blocks

14 words, ~0 minute read. Planted . Last tended to -.


Referenced by:Incremental SocialKronos

A proposal I want to write for posting signed content on your IndieWeb website

- +.


Referenced by:Incremental SocialKronos

A proposal I want to write for posting signed content on your IndieWeb website

+ \ No newline at end of file diff --git a/garden/the-small-web/index.html b/garden/the-small-web/index.html index fd4c196a0..cd9522e70 100644 --- a/garden/the-small-web/index.html +++ b/garden/the-small-web/index.html @@ -6,14 +6,14 @@ The Small Web | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

The Small Web

731 words, ~4 minute read. Planted +

Skip to content

The Small Web

731 words, ~4 minute read. Planted . Last tended to -.


Referenced by:CommuneDecentralized IdentityDigital LocalityFedi v2My Personal WebsiteThe IndieWeb/Signature BlocksThis Knowledge HubWebringsWeird

The small web (also known as the indie web, personal web, the web revival movement, and other terms) refers to small, personal, independent websites. It is seen as a direct alternative to the centralized and homogenized websites like X, Meta, and TikTok. My Personal Website is part of the small web!

Motivation behind the small web

The modern web is bad

The small web is, at its roots, a direct response to the issues with the modern web:

The modern web is dominated by a handful of large websites, sometimes referred to as the "corporate web". These websites limit personalization, how you can use the website, and are filled with ads, marketers, and influencers.

The corporate web is designed for consuming content created by a few large/popular creators. This manifests in the near-ubiquitous infinitely scrolling feed of algorithmically chosen posts, optimized to keep you on the site for as long as possible, to the detriment of society.

Large websites, due to the profit motive, will naturally Enshittify.

The old web was good

In contrast to the above, the classic web was filled with many diverse sites that typically represented a single person or organization, who were able to fully tailor their site to what they wanted it to be. Websites would be more unique and interesting, since the creator would have full control over them. This also makes the whole web feel more personal and intimate, as you're looking at a closer representation of how someone chooses to portray themselves online, in a way a profile page on X or Meta cannot be.

There are still lessons we've learned over time that can apply to modern "small web" pages, like accessible design and how to be more inclusive.

The small web is anti-corporate

Small static websites are very cheap to host, making anti-features like ads unnecessary and therefore rare. In general small websites are cheap enough to avoid needing to think about monetization entirely, let alone worrying about how to perpetually make more money. This lack of profit motive behind most small websites contributes to a culture of not just being "not corporate", but "anti-corporate".

In general, the corporate web seems to have values that align with those of authoritarianism - control, surveillance, and hierarchy, whereas the small web aligns with anarchist values - autonomy, cooperation, and egalitarianism.

Further reading

These are videos and articles that continue expanding on the values and motivations behind the small web as an alternative to the corporate web:

Browsing the small web

Follow Webrings or other links from known small websites.

Marginalia is a search engine for non-commercial content with a "random" button and filters for the small web explicitly (amongst other useful filters!)

The Tildeverse contains a large set of personal websites.

  • Pick one of the member sites, and they'll have a list of all their users, who each have a custom page. Some may also list most recently updated pages, which is a good way of filtering out default pages.
  • You may also consider joining one of these communities. They're effectively shared Linux computers, with a focus on small tight knit communities as an alternative to social media. Great if you're interested in learning Linux and command line utilities!

Building personal websites

IndieWeb contains various information and resources on building personal websites that use open standards to better interact with readers and other sites consistently. Check out IndieWebify Me to get assistance implementing their standards.

Free hosting for static websites:

Other resources:

Streams

Microsub is a proposed protocol to support hosting streams of content on personal websites in a way they can be consistently ingested by microsub clients. This way, people could subscribe to multiple streams on independent websites and get them in one feed. Through this, the indie web becomes a Federated Social Media.

Streams also allow your personal website to be the one source of truth for your posted content, in a concept called POSSE - Publish (on your) Own Site, Syndicate Elsewhere (other social media sites). This would effectively solve the problems described in Hey Creators, Please Make Firehoses!

Multiple streams can be hosted by one site/person so people can subscribe to the kind of content they're interested in.

Digital Gardens

These sites may be useful to occasionally check up on rather than get notifications from on every post/change

  • Although Garden-RSS could allow those who want to receive notifications to do so

The future

The Internet is a series of webs talks about transitioning from our current consolidated web back to the indie web

- +.


Referenced by:CommuneDecentralized IdentityDigital LocalityFedi v2My Personal WebsiteThe IndieWeb/Signature BlocksThis Knowledge HubWebringsWeird

The small web (also known as the indie web, personal web, the web revival movement, and other terms) refers to small, personal, independent websites. It is seen as a direct alternative to the centralized and homogenized websites like X, Meta, and TikTok. My Personal Website is part of the small web!

Motivation behind the small web

The modern web is bad

The small web is, at its roots, a direct response to the issues with the modern web:

The modern web is dominated by a handful of large websites, sometimes referred to as the "corporate web". These websites limit personalization, how you can use the website, and are filled with ads, marketers, and influencers.

The corporate web is designed for consuming content created by a few large/popular creators. This manifests in the near-ubiquitous infinitely scrolling feed of algorithmically chosen posts, optimized to keep you on the site for as long as possible, to the detriment of society.

Large websites, due to the profit motive, will naturally Enshittify.

The old web was good

In contrast to the above, the classic web was filled with many diverse sites that typically represented a single person or organization, who were able to fully tailor their site to what they wanted it to be. Websites would be more unique and interesting, since the creator would have full control over them. This also makes the whole web feel more personal and intimate, as you're looking at a closer representation of how someone chooses to portray themselves online, in a way a profile page on X or Meta cannot be.

There are still lessons we've learned over time that can apply to modern "small web" pages, like accessible design and how to be more inclusive.

The small web is anti-corporate

Small static websites are very cheap to host, making anti-features like ads unnecessary and therefore rare. In general small websites are cheap enough to avoid needing to think about monetization entirely, let alone worrying about how to perpetually make more money. This lack of profit motive behind most small websites contributes to a culture of not just being "not corporate", but "anti-corporate".

In general, the corporate web seems to have values that align with those of authoritarianism - control, surveillance, and hierarchy, whereas the small web aligns with anarchist values - autonomy, cooperation, and egalitarianism.

Further reading

These are videos and articles that continue expanding on the values and motivations behind the small web as an alternative to the corporate web:

Browsing the small web

Follow Webrings or other links from known small websites.

Marginalia is a search engine for non-commercial content with a "random" button and filters for the small web explicitly (amongst other useful filters!)

The Tildeverse contains a large set of personal websites.

  • Pick one of the member sites, and they'll have a list of all their users, who each have a custom page. Some may also list most recently updated pages, which is a good way of filtering out default pages.
  • You may also consider joining one of these communities. They're effectively shared Linux computers, with a focus on small tight knit communities as an alternative to social media. Great if you're interested in learning Linux and command line utilities!

Building personal websites

IndieWeb contains various information and resources on building personal websites that use open standards to better interact with readers and other sites consistently. Check out IndieWebify Me to get assistance implementing their standards.

Free hosting for static websites:

Other resources:

Streams

Microsub is a proposed protocol to support hosting streams of content on personal websites in a way they can be consistently ingested by microsub clients. This way, people could subscribe to multiple streams on independent websites and get them in one feed. Through this, the indie web becomes a Federated Social Media.

Streams also allow your personal website to be the one source of truth for your posted content, in a concept called POSSE - Publish (on your) Own Site, Syndicate Elsewhere (other social media sites). This would effectively solve the problems described in Hey Creators, Please Make Firehoses!

Multiple streams can be hosted by one site/person so people can subscribe to the kind of content they're interested in.

Digital Gardens

These sites may be useful to occasionally check up on rather than get notifications from on every post/change

  • Although Garden-RSS could allow those who want to receive notifications to do so

The future

The Internet is a series of webs talks about transitioning from our current consolidated web back to the indie web

+ \ No newline at end of file diff --git a/garden/this-knowledge-hub/index.html b/garden/this-knowledge-hub/index.html index 3ef429b03..f6282f020 100644 --- a/garden/this-knowledge-hub/index.html +++ b/garden/this-knowledge-hub/index.html @@ -6,14 +6,14 @@ This Knowledge Hub | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

This Knowledge Hub

231 words, ~1 minute read. Planted +

Skip to content

This Knowledge Hub

231 words, ~1 minute read. Planted . Last tended to -.


Referenced by:Digital Gardens

This is my knowledge hub! It's a Digital Garden collecting my thoughts in varying levels of completeness on basically anything I have interest in. It's wiki-style, but not like Wikipedia. Each page is going to be biased and argumentative, and based on my understanding of the concept at the time of writing (with regular updates to reflect new understandings). On the more fleshed out articles I'll typically adopt the structure of a persuasive essay and include sources.

Since starting this digital garden, I've been writing a lot. Brief hiatuses aside, I'm writing on something nearly every day. I keep a lot of pages private, including all my daily journal pages, and only make a garden page public once I'm sufficiently happy with the state of it. As time goes on, I should also update and improve older pages to meet any increase in standards new pages have. This process of writing and updating pages has really helped me collect my thoughts and essentially check my understanding of a topic.

I write to my garden using Logseq. For more details on how the site gets generated and hosted, check out the page on My Personal Website. Of note, pushing garden page updates to the site is not an automatic process (which applies to bridged timeline posts as well, such as from Youtube or Github), so it's possible I'll have updated pages locally but they're not reflected in the site immediately.

Until something like Garden-RSS exists, we'll have to make do with /changelog which gives a git diff summary for every pushed change, in the form of a The IndieWeb stream as well as an RSS feed.

- +.


Referenced by:Digital Gardens

This is my knowledge hub! It's a Digital Garden collecting my thoughts in varying levels of completeness on basically anything I have interest in. It's wiki-style, but not like Wikipedia. Each page is going to be biased and argumentative, and based on my understanding of the concept at the time of writing (with regular updates to reflect new understandings). On the more fleshed out articles I'll typically adopt the structure of a persuasive essay and include sources.

Since starting this digital garden, I've been writing a lot. Brief hiatuses aside, I'm writing on something nearly every day. I keep a lot of pages private, including all my daily journal pages, and only make a garden page public once I'm sufficiently happy with the state of it. As time goes on, I should also update and improve older pages to meet any increase in standards new pages have. This process of writing and updating pages has really helped me collect my thoughts and essentially check my understanding of a topic.

I write to my garden using Logseq. For more details on how the site gets generated and hosted, check out the page on My Personal Website. Of note, pushing garden page updates to the site is not an automatic process (which applies to bridged timeline posts as well, such as from Youtube or Github), so it's possible I'll have updated pages locally but they're not reflected in the site immediately.

Until something like Garden-RSS exists, we'll have to make do with /changelog which gives a git diff summary for every pushed change, in the form of a The IndieWeb stream as well as an RSS feed.

+ \ No newline at end of file diff --git a/garden/trans-athletes-in-sports/index.html b/garden/trans-athletes-in-sports/index.html index 0e1e14909..75c759533 100644 --- a/garden/trans-athletes-in-sports/index.html +++ b/garden/trans-athletes-in-sports/index.html @@ -6,14 +6,14 @@ Trans athletes in sports | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Trans athletes in sports

288 words, ~2 minute read. Planted +

Skip to content

Trans athletes in sports

288 words, ~2 minute read. Planted . Last tended to -.


Referenced by:Everything is Political

Sports are meant to be competitions with winners and losers, which means intrinsically that one has to be better than the other. But we've determined certain advantages as "fair" ones and others as not, without fully acknowledging how fairness is just a Social Construct.

When Michael Phelps won gold medal after gold medal, no one complained that his naturally webbed feet were an "unfair" advantage, or put him in a separate league like we do for Gender. But when Caster Semenya, a cis woman with naturally higher levels of testosterone than other women, wanted to compete in track and field internationally she was told she'd need to take testosterone reducing medicine (until she years later won the case in Europe's human rights court, with caveats). If you have ADHD you're allowed to take performance enhancing drugs, but otherwise not. Coffee and protein could clearly be classified as performance enhancing drugs but for the fact we've socially defined PED as narrowly avoiding those substances. These are arbitrary rules that only seem fair to some people, because there is no objective fairness. So when trans athletes are attacked both when they compete with those of their assigned gender at birth as well as when they compete with those of their preferred gender, it's clear the motivation behind it all is not really about fairness in sports, but about making trans people go away. And yet, trans athletes tend to be an issue where even many socially leftist voices will discuss how "complicated" this issue is and even spread the idea that anti-trans policies are required in order to preserve fairness, such as The Young Turks as described in Why I Left TYT.

Being trans should not mean you are banned from competing or relegated to a division for just trans people. The argument is usually that trans individuals are either currently receiving or used to receive larger amounts of testosterone than those they'd be competing with. But the competition isn't about who has the more testosterone. Well, the argument continues, testosterone levels may be indicative of increased muscle growth. But muscle growth also isn't what the competition is about. It can be argued to indicate performance at the actual sport/activity the competition is over, but at this point isn't it too many layers of imperfect abstractions and assumptions? The person who wins is less tied to their actual ability and who happens to come out on top on each of these specific estimations.

There are many advantages one might have in sports, but contrary to a true meritocracy, our arbitrary distinctions on allowed vs disallowed advantages exposes the biases of our society, which are often racist, sexist, and transphobic. Therefore, appeals to "fairness" are explicit endorsements of those biases, namely bigotry.

I also support idubbbz discussing his support for trans athletes in 100 percent women, coming from the context of a boxer who has ran boxing competitions.

- +.


Referenced by:Everything is Political

Sports are meant to be competitions with winners and losers, which means intrinsically that one has to be better than the other. But we've determined certain advantages as "fair" ones and others as not, without fully acknowledging how fairness is just a Social Construct.

When Michael Phelps won gold medal after gold medal, no one complained that his naturally webbed feet were an "unfair" advantage, or put him in a separate league like we do for Gender. But when Caster Semenya, a cis woman with naturally higher levels of testosterone than other women, wanted to compete in track and field internationally she was told she'd need to take testosterone reducing medicine (until she years later won the case in Europe's human rights court, with caveats). If you have ADHD you're allowed to take performance enhancing drugs, but otherwise not. Coffee and protein could clearly be classified as performance enhancing drugs but for the fact we've socially defined PED as narrowly avoiding those substances. These are arbitrary rules that only seem fair to some people, because there is no objective fairness. So when trans athletes are attacked both when they compete with those of their assigned gender at birth as well as when they compete with those of their preferred gender, it's clear the motivation behind it all is not really about fairness in sports, but about making trans people go away. And yet, trans athletes tend to be an issue where even many socially leftist voices will discuss how "complicated" this issue is and even spread the idea that anti-trans policies are required in order to preserve fairness, such as The Young Turks as described in Why I Left TYT.

Being trans should not mean you are banned from competing or relegated to a division for just trans people. The argument is usually that trans individuals are either currently receiving or used to receive larger amounts of testosterone than those they'd be competing with. But the competition isn't about who has the more testosterone. Well, the argument continues, testosterone levels may be indicative of increased muscle growth. But muscle growth also isn't what the competition is about. It can be argued to indicate performance at the actual sport/activity the competition is over, but at this point isn't it too many layers of imperfect abstractions and assumptions? The person who wins is less tied to their actual ability and who happens to come out on top on each of these specific estimations.

There are many advantages one might have in sports, but contrary to a true meritocracy, our arbitrary distinctions on allowed vs disallowed advantages exposes the biases of our society, which are often racist, sexist, and transphobic. Therefore, appeals to "fairness" are explicit endorsements of those biases, namely bigotry.

I also support idubbbz discussing his support for trans athletes in 100 percent women, coming from the context of a boxer who has ran boxing competitions.

+ \ No newline at end of file diff --git a/garden/v-ecs/index.html b/garden/v-ecs/index.html index 3fcbf6bef..678e4a5ce 100644 --- a/garden/v-ecs/index.html +++ b/garden/v-ecs/index.html @@ -6,14 +6,14 @@ V-ecs | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

V-ecs

209 words, ~1 minute read. Planted +

Skip to content

V-ecs

209 words, ~1 minute read. Planted . Last tended to -.


Tags:My Projects

V-ecs (pronounced "Vex") is a Vulkan-based engine I made for making highly moddable games and tools in Lua centered around the ECS design pattern and a work-stealing job system.

The engine works with "worlds", which are collections of systems and renderers. The engine comes with several worlds using systems and renderers I made, including a voxel world, an incremental game, and some test scenes. All of these include systems to render the fps as well as show a debug console by typing the grave key (`). The default world is a title screen that detects any worlds in the "worlds" folder and displays a button for each of them.

The original plans were to eventually put it on the steam workshop so people could more easily share their creations amongst each other, but I never became happy enough with the performance of the engine - the parallelization of the lua code involved a lot of overhead that severely limited performance.

Instead, I made a couple of worlds by myself - an infinite procedurally generated voxel world, a simple incremental game, and a more complex incremental game I call "Sands of Time".

The gameplay of Sands of Time was replicated in Kronos Chapter 2!

- +.


Tags:My Projects

V-ecs (pronounced "Vex") is a Vulkan-based engine I made for making highly moddable games and tools in Lua centered around the ECS design pattern and a work-stealing job system.

The engine works with "worlds", which are collections of systems and renderers. The engine comes with several worlds using systems and renderers I made, including a voxel world, an incremental game, and some test scenes. All of these include systems to render the fps as well as show a debug console by typing the grave key (`). The default world is a title screen that detects any worlds in the "worlds" folder and displays a button for each of them.

The original plans were to eventually put it on the steam workshop so people could more easily share their creations amongst each other, but I never became happy enough with the performance of the engine - the parallelization of the lua code involved a lot of overhead that severely limited performance.

Instead, I made a couple of worlds by myself - an infinite procedurally generated voxel world, a simple incremental game, and a more complex incremental game I call "Sands of Time".

The gameplay of Sands of Time was replicated in Kronos Chapter 2!

+ \ No newline at end of file diff --git a/garden/video-essays/index.html b/garden/video-essays/index.html index 388805870..72c024fdf 100644 --- a/garden/video-essays/index.html +++ b/garden/video-essays/index.html @@ -6,14 +6,14 @@ Video Essays | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Video Essays

561 words, ~3 minute read. Planted +

Skip to content

Video Essays

561 words, ~3 minute read. Planted . Last tended to -.


Video essayists are an interesting case study here. I love video essays, they're often entertaining and you can tell the effort and care put into them. A lot of my favorite creators are video essayists, like hbomberguy, Folding Ideas, and Philosophy Tube (and probably more - its hard to keep track of my favorites since they upload infrequently). Unfortunately, video essays have now been recognized as successful ways to make videos with high watch time which has led to an explosion of video essays, with varying levels of skill, ethics, and effort put into researching the topics.

The format of video essays makes them feel credible - being longform, speaking authoritatively, and including relevant footage all contribute to this. However, none of those actually necessitate the creator being a subject matter expert.

"Video essayists" as a concept is a bit concerning because it positions those creators on a treadmill of constantly having to be (or at least appear to be) an expert of a brand new topic. I'm skeptical of any video essayist that uploads frequently or across a very large variety of topics.

Sometimes the extra duration of the footage is less to do with it deeply diving into the subject matter, but padding and fluff that's tangential to the point of the video. This is stuff like describing the process of how the creator did online research, or the methods they used to reach out to relevant people. In addition to padding the runtime, this shifts the focus off the subject of the video and onto the creator. I found this video to exemplify both this issue and many of my qualms with video essays.

Media Analysis Video Essays

Some video essays are very easy to make quickly and are doing so for profit. No video essay exemplifies this more than the media analysis video essay. While this doesn't apply to all video essays over media, all too often they'll just be summarizations of popular and nostalgic media that never gets into any meaningful analysis or offering genuine insights. It's just an easy way to make a lot of content, and thus watch time.

Personally, I think these specific video essays are slop taking advantage of people who like having their intellectual ego stroked. By watching media get lightly criticized, we position ourselves above the people actually out there creating original media. These videos are for the pretentious, who likely watch far more analysis of original media than original media itself. It's reaction content for those who feel they're above reaction content. This video essay (heh) goes further into the issues with this type of video essay.

Self Reflection

Part of my feelings towards video essays, and indeed such strong feelings as to include it here where its tangential at best, stems from self-confidence issues. Wondering if these articles I write are any better. I criticize video essays for being critical like an ouroboros, relying on this very statement to at least prove I'm aware of the hypocrisy.

Further Reading

Hey, did you know there's video essays about how video essays are bad? Well of course they are, a natural extension of the "thing bad" trend exemplified in the media analysis video essays and in Youtube culture at large. Anyways, I enjoyed this video covering other criticisms of video essays on Youtube.

Perhaps tangential, but I like Noodle's videos and he has one about critiquing video games, particularly popular titles.

- +.


Video essayists are an interesting case study here. I love video essays, they're often entertaining and you can tell the effort and care put into them. A lot of my favorite creators are video essayists, like hbomberguy, Folding Ideas, and Philosophy Tube (and probably more - its hard to keep track of my favorites since they upload infrequently). Unfortunately, video essays have now been recognized as successful ways to make videos with high watch time which has led to an explosion of video essays, with varying levels of skill, ethics, and effort put into researching the topics.

The format of video essays makes them feel credible - being longform, speaking authoritatively, and including relevant footage all contribute to this. However, none of those actually necessitate the creator being a subject matter expert.

"Video essayists" as a concept is a bit concerning because it positions those creators on a treadmill of constantly having to be (or at least appear to be) an expert of a brand new topic. I'm skeptical of any video essayist that uploads frequently or across a very large variety of topics.

Sometimes the extra duration of the footage is less to do with it deeply diving into the subject matter, but padding and fluff that's tangential to the point of the video. This is stuff like describing the process of how the creator did online research, or the methods they used to reach out to relevant people. In addition to padding the runtime, this shifts the focus off the subject of the video and onto the creator. I found this video to exemplify both this issue and many of my qualms with video essays.

Media Analysis Video Essays

Some video essays are very easy to make quickly and are doing so for profit. No video essay exemplifies this more than the media analysis video essay. While this doesn't apply to all video essays over media, all too often they'll just be summarizations of popular and nostalgic media that never gets into any meaningful analysis or offering genuine insights. It's just an easy way to make a lot of content, and thus watch time.

Personally, I think these specific video essays are slop taking advantage of people who like having their intellectual ego stroked. By watching media get lightly criticized, we position ourselves above the people actually out there creating original media. These videos are for the pretentious, who likely watch far more analysis of original media than original media itself. It's reaction content for those who feel they're above reaction content. This video essay (heh) goes further into the issues with this type of video essay.

Self Reflection

Part of my feelings towards video essays, and indeed such strong feelings as to include it here where its tangential at best, stems from self-confidence issues. Wondering if these articles I write are any better. I criticize video essays for being critical like an ouroboros, relying on this very statement to at least prove I'm aware of the hypocrisy.

Further Reading

Hey, did you know there's video essays about how video essays are bad? Well of course they are, a natural extension of the "thing bad" trend exemplified in the media analysis video essays and in Youtube culture at large. Anyways, I enjoyed this video covering other criticisms of video essays on Youtube.

Perhaps tangential, but I like Noodle's videos and he has one about critiquing video games, particularly popular titles.

+ \ No newline at end of file diff --git a/garden/video-game-monetization/index.html b/garden/video-game-monetization/index.html index 9ba44e8b4..aca4776e5 100644 --- a/garden/video-game-monetization/index.html +++ b/garden/video-game-monetization/index.html @@ -6,14 +6,14 @@ Video Game Monetization | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Video Game Monetization

250 words, ~1 minute read. Planted +

Skip to content

Video Game Monetization

250 words, ~1 minute read. Planted . Last tended to -.


Referenced by:Life is Strange

AAA games

They Clcost a lot of money to make, mostly due to the graphics arms race. The price required to make these games profitable would be much higher than the current price of AAA games.

Graphics would not justify significantly higher prices, and AAA studios know this. So instead they use the techniques to make more money without raising the base price:

Free-to-play games

Typically utilize MTX and ads in order to profit. Often extreme cases of designing games to compell players to spend money.

Indie developers

Trying to make a sustainable living as an indie developer is hard. The industry is packed with lots of competition, and drive prices people are willing to pay very low. Therefore, I don't blame indies for their monetization strategies, even if I consider them unethical or tainting the game design.

Ethical game monetization

Requirements:

  • Free demo
  • Paid base game
  • No MTX
  • Paid content expansions

The goal of the above is to allow players to determine if they enjoy the game without putting money down, and to ensure the game design cannot be tainted by the monetization.

I think having the gameplay affected by transactions of any kind taints the game design. This is a particularly controversial take in the context of communal benefits (e.g. one person donates and all players get a 2x buff for an hour, or a persistent buff based on number of patrons), which are generally seen as ethical.

- +.


Referenced by:Life is Strange

AAA games

They Clcost a lot of money to make, mostly due to the graphics arms race. The price required to make these games profitable would be much higher than the current price of AAA games.

Graphics would not justify significantly higher prices, and AAA studios know this. So instead they use the techniques to make more money without raising the base price:

Free-to-play games

Typically utilize MTX and ads in order to profit. Often extreme cases of designing games to compell players to spend money.

Indie developers

Trying to make a sustainable living as an indie developer is hard. The industry is packed with lots of competition, and drive prices people are willing to pay very low. Therefore, I don't blame indies for their monetization strategies, even if I consider them unethical or tainting the game design.

Ethical game monetization

Requirements:

  • Free demo
  • Paid base game
  • No MTX
  • Paid content expansions

The goal of the above is to allow players to determine if they enjoy the game without putting money down, and to ensure the game design cannot be tainted by the monetization.

I think having the gameplay affected by transactions of any kind taints the game design. This is a particularly controversial take in the context of communal benefits (e.g. one person donates and all players get a 2x buff for an hour, or a persistent buff based on number of patrons), which are generally seen as ethical.

+ \ No newline at end of file diff --git a/garden/virality/index.html b/garden/virality/index.html index cdd995607..d196e9086 100644 --- a/garden/virality/index.html +++ b/garden/virality/index.html @@ -6,14 +6,14 @@ Virality | The Paper Pilot - + - + - - - + + + @@ -53,9 +53,9 @@ -
Skip to content

Virality

396 words, ~2 minute read. Planted -.


Referenced by:Digital Locality

Virality is the ability of something to "go viral" on a network - spread far and wide throughout the network. On traditional social media, this refers to how influencers and advertisers will have their content spread, but also specific posts from smaller posters can get picked up by the algorithm and spread as well.

Since there's only so much of people's attention to go around, social media has been described as an "attention economy". Under this framework, one could argue that social media is designed for "wealth accumulation", elevating a handful of accounts to celebrity status and limiting the reach of the masses. This dynamic much reflects the class antagonisms in a capitalist economy.

People "going viral"

On traditional social media, posts can be picked up by the algorithm and spread far and wide, causing the author to be inundated with unwanted attention, including negative or hateful attention. This can and has caused serious harm for both businesses and especially individuals. Traditional social media doesn't differentiate between the "living room" and "public square", which enforces this behavior. Digital Locality could help with this by its tendency to limit the reach of individual people or posts.

Movements on the fediverse

The Fediverse has been criticized for being "anti-viral", as described by Dr. Jonathan Flowers in a series of posts on whether the 2020 BLM movement could have happened on the fediverse. In general, I think something more Decentralized will fix these issues, so I'll address his main points.

Hashtags

Dr. Flowers argues that the success of BLM was dependent on the movement not relying on any specific person or post, but rather having the "cripthevote' hashtag that was visible platform wide and allowed people to see many posts about the movement and check for updates in realtime.

However, on the fediverse hashtags are instance local. This means they have to "jump" between instances (or escape, as he refers to it) in order to spread. This makes the movement much harder to spread across the federated network.

This may be solved by more properly Decentralized Social Media, since without a concept of instances there would naturally no longer be instance-local hashtags.

"No Politics" Rules

Since some instances on the fediverse have "no politics" rules, movements (which are inherently political) may be suppressed. Since identities are attached to instances, this means those users essentially cannot participate in the movement. Coupled with the usual issues with "no politics" rules, movements can be seriously impeded on the fediverse.

Decentralized Moderation can fix this issue by giving individuals more agency in moderation, and allowing them to evaluate their participation in movements on a case-by-case movement rather than relying on a blanket "no politics" rule

- +
Skip to content

Virality

396 words, ~2 minute read. Planted +.


Referenced by:Digital Locality

Virality is the ability of something to "go viral" on a network - spread far and wide throughout the network. On traditional social media, this refers to how influencers and advertisers will have their content spread, but also specific posts from smaller posters can get picked up by the algorithm and spread as well.

Since there's only so much of people's attention to go around, social media has been described as an "attention economy". Under this framework, one could argue that social media is designed for "wealth accumulation", elevating a handful of accounts to celebrity status and limiting the reach of the masses. This dynamic much reflects the class antagonisms in a capitalist economy.

People "going viral"

On traditional social media, posts can be picked up by the algorithm and spread far and wide, causing the author to be inundated with unwanted attention, including negative or hateful attention. This can and has caused serious harm for both businesses and especially individuals. Traditional social media doesn't differentiate between the "living room" and "public square", which enforces this behavior. Digital Locality could help with this by its tendency to limit the reach of individual people or posts.

Movements on the fediverse

The Fediverse has been criticized for being "anti-viral", as described by Dr. Jonathan Flowers in a series of posts on whether the 2020 BLM movement could have happened on the fediverse. In general, I think something more Decentralized will fix these issues, so I'll address his main points.

Hashtags

Dr. Flowers argues that the success of BLM was dependent on the movement not relying on any specific person or post, but rather having the "cripthevote' hashtag that was visible platform wide and allowed people to see many posts about the movement and check for updates in realtime.

However, on the fediverse hashtags are instance local. This means they have to "jump" between instances (or escape, as he refers to it) in order to spread. This makes the movement much harder to spread across the federated network.

This may be solved by more properly Decentralized Social Media, since without a concept of instances there would naturally no longer be instance-local hashtags.

"No Politics" Rules

Since some instances on the fediverse have "no politics" rules, movements (which are inherently political) may be suppressed. Since identities are attached to instances, this means those users essentially cannot participate in the movement. Coupled with the usual issues with "no politics" rules, movements can be seriously impeded on the fediverse.

Decentralized Moderation can fix this issue by giving individuals more agency in moderation, and allowing them to evaluate their participation in movements on a case-by-case movement rather than relying on a blanket "no politics" rule

+ \ No newline at end of file diff --git a/garden/vitepress/index.html b/garden/vitepress/index.html index 25d7512e4..a97fa337f 100644 --- a/garden/vitepress/index.html +++ b/garden/vitepress/index.html @@ -6,14 +6,14 @@ Vitepress | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Vitepress

4 words, ~0 minute read. Planted +

Skip to content

Vitepress

4 words, ~0 minute read. Planted . Last tended to -.


Referenced by:My Personal Website

Vitepress is an Open Source static site generator

- +.


Referenced by:My Personal Website

Vitepress is an Open Source static site generator

+ \ No newline at end of file diff --git a/garden/wanderstop/index.html b/garden/wanderstop/index.html index 839df0c97..2c0c597fe 100644 --- a/garden/wanderstop/index.html +++ b/garden/wanderstop/index.html @@ -6,14 +6,14 @@ Wanderstop | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Wanderstop

8 words, ~0 minute read. Planted +

Skip to content

Wanderstop

8 words, ~0 minute read. Planted . Last tended to -.


Tags:Davey Wreden

Wanderstop is the first game by Ivy Road. It's a narrative focused cozy game

- +.


Tags:Davey Wreden

Wanderstop is the first game by Ivy Road. It's a narrative focused cozy game

+ \ No newline at end of file diff --git a/garden/webrings/index.html b/garden/webrings/index.html index f41b9414a..f4458600b 100644 --- a/garden/webrings/index.html +++ b/garden/webrings/index.html @@ -6,14 +6,14 @@ Webrings | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Webrings

139 words, ~1 minute read. Planted +

Skip to content

Webrings

139 words, ~1 minute read. Planted . Last tended to -.


Referenced by:The Small Web

A collection of Personal Websites that link to each other

  • These websites are all endorsing each other
  • They form a network of related sites readers might be interested in
  • Built on human trust rather than algorithms

Commune has a vision for modern webrings

  • Have communities set up matrix spaces for chatting
  • Multiple spaces can contain the same room
  • Related communities can share a room about a relevant topic
    • e.g. a bunch of game development libraries shared a "Game Design" room
  • This allows smaller communities to grow from cross-pollinating with other related communities
  • Could Incremental Social host a shared "Incremental Games" room?
    • How to bridge one channel to multiple discord servers, since that's where most incremental games communities are
    • Would this be appealing to already large communities?
    • Would this be overwhelming to smaller communities?
    • Who would moderate?
- +.


Referenced by:The Small Web

A collection of Personal Websites that link to each other

  • These websites are all endorsing each other
  • They form a network of related sites readers might be interested in
  • Built on human trust rather than algorithms

Commune has a vision for modern webrings

  • Have communities set up matrix spaces for chatting
  • Multiple spaces can contain the same room
  • Related communities can share a room about a relevant topic
    • e.g. a bunch of game development libraries shared a "Game Design" room
  • This allows smaller communities to grow from cross-pollinating with other related communities
  • Could Incremental Social host a shared "Incremental Games" room?
    • How to bridge one channel to multiple discord servers, since that's where most incremental games communities are
    • Would this be appealing to already large communities?
    • Would this be overwhelming to smaller communities?
    • Who would moderate?
+ \ No newline at end of file diff --git a/garden/weird/index.html b/garden/weird/index.html index 0a7e02f60..f70e22f34 100644 --- a/garden/weird/index.html +++ b/garden/weird/index.html @@ -6,14 +6,14 @@ Weird | The Paper Pilot - + - + - - - + + + @@ -53,10 +53,10 @@ -
Skip to content

Weird

114 words, ~1 minute read. Planted +

Skip to content

Weird

114 words, ~1 minute read. Planted . Last tended to -.


Referenced by:CommuneFedi v2The Small Web

Weird is an Open Source project by the Commune team currently in development

Aims to make creating Personal Websites with Decentralized Identity available to everyone

  • Also plans on having paid tiers for giving people access to single user instances of various Fediverse tools

Long term, Weird wants to build a new better fediverse

- +.


Referenced by:CommuneFedi v2The Small Web

Weird is an Open Source project by the Commune team currently in development

Aims to make creating Personal Websites with Decentralized Identity available to everyone

  • Also plans on having paid tiers for giving people access to single user instances of various Fediverse tools

Long term, Weird wants to build a new better fediverse

+ \ No newline at end of file diff --git a/guide-to-incrementals/design/criticism/index.html b/guide-to-incrementals/design/criticism/index.html index 123a151c8..1861d931b 100644 --- a/guide-to-incrementals/design/criticism/index.html +++ b/guide-to-incrementals/design/criticism/index.html @@ -6,14 +6,14 @@ Guide to Incrementals/Navigating Criticism | The Paper Pilot - + - + - - - + + + @@ -51,10 +51,10 @@ -
Skip to content

Guide to Incrementals/Navigating Criticism

747 words, ~4 minute read. Planted +

Skip to content

Guide to Incrementals/Navigating Criticism

747 words, ~4 minute read. Planted . Last tended to -.


Referenced by:Incremental SocialKronos

Developing games is fun and exciting and teaches a lot of wonderful skills - I enthusiastically encourage anyone with an interest in game development to try it out - and incremental games are a wonderful way to get started. However, there are many challenges young and inexperienced developers have to face, and I think the hardest one - harder than coding, debugging, balancing, etc. - is handling criticism. When you put your heart and soul into a game it is natural to feel very vulnerable. While I think there's a lot communities can do to ensure they're welcoming, positive and constructive with their criticisms, inevitably you will eventually read some, and potentially a lot, of comments that can deeply affect you. No one is immune to this, from young incremental game developers to the largest content creators you can think of. That's why it's important to be able to process and navigate criticism, because ultimately collecting feedback is essential to the journey to becoming a better developer. On this page, we'll explore how to embrace criticism, grow from it, and continue to post your games publicly with confidence.

Reading Feedback

Game development is a skill that takes time and practice to get truly great at. Criticism and other constructive feedback are vital to continually improving. It's useful to look at the criticism as solely a tool for improving this game and future games - that is to say, it should never be used against you as a person. Insults towards the developer(s) themselves are never okay and should not be allowed within whatever community you're sharing your works in. If you do come across a comment you interpret as an attack upon your person, you should report it. For other negative comments, try not to internalize them; instead, focus on improving the game. By distancing your own identity from your work emotionally, you can better analyze the game and use the feedback to your advantage.

Not all feedback is made equal, and you don't need to feel compelled to read and obey every piece of feedback you receive. Learn to distinguish between constructive feedback and unhelpful comments. Constructive feedback typically offers specific suggestions for improvement, while unhelpful comments are often vague or hurtful. Prioritize the former and disregard the latter. That said, most feedback you get will not be from game developers, so take specific suggestions with a grain of salt. Determine the actual problem they're experiencing, and design what you believe the best solution to that problem would be, regardless if that's the specific solution the player asked for. And keep in mind, due to different player preferences you'll never satisfy everyone, and you don't need to. Ultimately if even just you find the game fun, then that's a success.

Seeking Feedback

When deciding where to share your game, consider the type of players you anticipate getting, and the kind of feedback you can anticipate receiving. Different communities will have different levels of support for learning developers, and certain communities may prefer certain types of games or mechanics. It's important to get a diverse set of feedback focused on players you think will enjoy the specific game you're making.

Collecting feedback from other game developers is incredibly helpful. They've trained themselves to recognize good and bad game design and how to articulate the differences, and from my experience are much more likely to leave positive and constructive comments since they've been in your shoes before! They understand the struggles and can offer guidance and emotional support.

Responding to Feedback

Negative feedback can naturally feel like an attack, and it's okay to get angry. However, lashing back is never the appropriate response. It's best to cool off IRL, and keep in mind all the positive comments you've received. There's a concept in Psychology called negative bias that explains how negative feedback tends to stick with us much more prominently than positive feedback, so it's useful to regularly remind yourself of all the positive feedback you've received. Celebrate your successes, no matter how small they may seem - getting a game to a state you can publicly share it with people is an accomplishment in and of itself!

Remember your passion and your initial reasons for getting into game development. The journey will have its ups and downs, but staying true to your vision and passion will keep you motivated.

- +.


Referenced by:Incremental SocialKronos

Developing games is fun and exciting and teaches a lot of wonderful skills - I enthusiastically encourage anyone with an interest in game development to try it out - and incremental games are a wonderful way to get started. However, there are many challenges young and inexperienced developers have to face, and I think the hardest one - harder than coding, debugging, balancing, etc. - is handling criticism. When you put your heart and soul into a game it is natural to feel very vulnerable. While I think there's a lot communities can do to ensure they're welcoming, positive and constructive with their criticisms, inevitably you will eventually read some, and potentially a lot, of comments that can deeply affect you. No one is immune to this, from young incremental game developers to the largest content creators you can think of. That's why it's important to be able to process and navigate criticism, because ultimately collecting feedback is essential to the journey to becoming a better developer. On this page, we'll explore how to embrace criticism, grow from it, and continue to post your games publicly with confidence.

Reading Feedback

Game development is a skill that takes time and practice to get truly great at. Criticism and other constructive feedback are vital to continually improving. It's useful to look at the criticism as solely a tool for improving this game and future games - that is to say, it should never be used against you as a person. Insults towards the developer(s) themselves are never okay and should not be allowed within whatever community you're sharing your works in. If you do come across a comment you interpret as an attack upon your person, you should report it. For other negative comments, try not to internalize them; instead, focus on improving the game. By distancing your own identity from your work emotionally, you can better analyze the game and use the feedback to your advantage.

Not all feedback is made equal, and you don't need to feel compelled to read and obey every piece of feedback you receive. Learn to distinguish between constructive feedback and unhelpful comments. Constructive feedback typically offers specific suggestions for improvement, while unhelpful comments are often vague or hurtful. Prioritize the former and disregard the latter. That said, most feedback you get will not be from game developers, so take specific suggestions with a grain of salt. Determine the actual problem they're experiencing, and design what you believe the best solution to that problem would be, regardless if that's the specific solution the player asked for. And keep in mind, due to different player preferences you'll never satisfy everyone, and you don't need to. Ultimately if even just you find the game fun, then that's a success.

Seeking Feedback

When deciding where to share your game, consider the type of players you anticipate getting, and the kind of feedback you can anticipate receiving. Different communities will have different levels of support for learning developers, and certain communities may prefer certain types of games or mechanics. It's important to get a diverse set of feedback focused on players you think will enjoy the specific game you're making.

Collecting feedback from other game developers is incredibly helpful. They've trained themselves to recognize good and bad game design and how to articulate the differences, and from my experience are much more likely to leave positive and constructive comments since they've been in your shoes before! They understand the struggles and can offer guidance and emotional support.

Responding to Feedback

Negative feedback can naturally feel like an attack, and it's okay to get angry. However, lashing back is never the appropriate response. It's best to cool off IRL, and keep in mind all the positive comments you've received. There's a concept in Psychology called negative bias that explains how negative feedback tends to stick with us much more prominently than positive feedback, so it's useful to regularly remind yourself of all the positive feedback you've received. Celebrate your successes, no matter how small they may seem - getting a game to a state you can publicly share it with people is an accomplishment in and of itself!

Remember your passion and your initial reasons for getting into game development. The journey will have its ups and downs, but staying true to your vision and passion will keep you motivated.

+ \ No newline at end of file diff --git a/guide-to-incrementals/index.html b/guide-to-incrementals/index.html index 20ea0ee75..9b44da83d 100644 --- a/guide-to-incrementals/index.html +++ b/guide-to-incrementals/index.html @@ -6,14 +6,14 @@ Guide to Incrementals | The Paper Pilot - + - + - - - + + + @@ -51,10 +51,10 @@ -
Skip to content

Guide to Incrementals

230 words, ~1 minute read. Planted +

Skip to content

Guide to Incrementals

230 words, ~1 minute read. Planted . Last tended to -.


Referenced by:My Personal Website

This is a comprehensive guide to Incremental Games, a genre of video games. It will explore defining the genre, why it's appealing, and how to design and build your own incremental game. Along the way will be interactive examples, snippets from other creators, and relevant material to contextualize everything.

Note: This is an incomplete document. I want to keep adding opinions and opposing views from other incremental games developers, and add interactive examples to illustrate various points regarding game design and balancing. Consider this a living document - and see the changelog at the end.

Why am I making this?

That's a good question! What authority do I have to be making this guide? I haven't made the best incremental games, nor the most incremental games, certainly not the most popular ones either. But I do have some formal education in game development, know a lot of incremental game devs (as well as other game devs), and have a passionate interest in ludology, classifying genres, etc. I've also made a couple of incremental games) myself.

If you have any additional questions about my credentials or anything on this site, feel free to reach out!

Ludology

Making an Incremental

- +.


Referenced by:My Personal Website

This is a comprehensive guide to Incremental Games, a genre of video games. It will explore defining the genre, why it's appealing, and how to design and build your own incremental game. Along the way will be interactive examples, snippets from other creators, and relevant material to contextualize everything.

Note: This is an incomplete document. I want to keep adding opinions and opposing views from other incremental games developers, and add interactive examples to illustrate various points regarding game design and balancing. Consider this a living document - and see the changelog at the end.

Why am I making this?

That's a good question! What authority do I have to be making this guide? I haven't made the best incremental games, nor the most incremental games, certainly not the most popular ones either. But I do have some formal education in game development, know a lot of incremental game devs (as well as other game devs), and have a passionate interest in ludology, classifying genres, etc. I've also made a couple of incremental games) myself.

If you have any additional questions about my credentials or anything on this site, feel free to reach out!

Ludology

Making an Incremental

+ \ No newline at end of file diff --git a/guide-to-incrementals/ludology/appeal-developers/index.html b/guide-to-incrementals/ludology/appeal-developers/index.html index 6834ac908..9c0deda77 100644 --- a/guide-to-incrementals/ludology/appeal-developers/index.html +++ b/guide-to-incrementals/ludology/appeal-developers/index.html @@ -6,14 +6,14 @@ Guide to Incrementals/Appeal to Developers | The Paper Pilot - + - + - - - + + + @@ -51,10 +51,10 @@ -
Skip to content

Guide to Incrementals/Appeal to Developers

636 words, ~3 minute read. Planted +

Skip to content

Guide to Incrementals/Appeal to Developers

636 words, ~3 minute read. Planted . Last tended to -.


Referenced by:Incremental SocialKronos

There are a lot of developers in the incremental games community - the genre seems to draw them in, and convert a lot of players into developers. Let's explore the reasons why this genre appeals to developers.

Incrementals are Easy to Make

Compared to other genres, incrementals have quite low expectations. You don't need to make fancy art, or music, or lay things out nicely. If you can make a button and learn the few lines of code necessary to make a number go up, you can make an incremental. This low threshold makes the genre perfect for those who are actively learning to code and haven't developed any gamedev-related skills yet.

Additionally, unlike other genres incrementals are uniquely easy to implement in a normal web page - no need to worry about rendering sprites, moving them around, implementing physics, etc. New developers can just use HTML to add a button, and the game is now available in your browser. You don't need to choose an engine, have admin privileges, or hell for the dedicated you don't even need a computer - there are tools for web development that run in the browser itself, so you can technically use your phone if that's all you have.

Javascript is a perfectly viable language for making web games, whereas other genres are typically going to require using other more difficult languages to learn. There are countless javascript tutorials that start from 0 knowledge of programming, making it incredibly accessible to beginners.

Players are Easy to Find

Once you've finished your game and uploaded it on github pages or itch or just copied the link if you're using glitch or replit (all of which are easy to do), anyone can now play the game in their browser. This low barrier to entry has shown tremendous success in getting completely unknown developers to have thousands of plays.

The incremental games community, which mostly centers around r/incremental_games, is always looking for new games and tends to flood any new ones posted with initial players.

Having your games be played can be incredibly motivating, and the community makes it quite clear that you can expect players to play your game. These communities - both for incremental games in general as well as game-specific communities - tend to be very developer friendly as well. A lot of the developers know each other, and welcome new developers with open arms, often with dedicated channels for programming help and discussions.

Monetization

I'd like to clarify that everything I've said above mainly applies to web-based incrementals. Incremental games are also incredibly popular on mobile, but with a much different culture and community. Many mobile gamers will still participate in the web-focused community for the culture. This web-focused community has a culture that has been criticized for being "anti-monetization". Ads, IAPs, and similar forms of monetization are often criticized, mainly due to the abundance of completely non-monetized games available from hobbyist developers. There are exceptions, like paid games often being considered fine, like Increlution or Stuck in Time, or donation ware games like kittens game, but even popular games that have IAP see some level of regular criticism, like NGU Idle, Idle Skilling, or Idle Pins. A large part of this can be explained by the community being hyper-aware of the addictive) nature of this genre and its susceptibility to exploiting players.

On mobile, however, monetization is the norm and expected. If an incremental game is available on mobile, it almost certainly will be monetized, and mobile players are aware and accepting of that. Mobile incremental games, due to their addictive nature, tend to make a lot of money. It's very lucrative, and therefore these games are quite abundant on mobile storefronts.

- +.


Referenced by:Incremental SocialKronos

There are a lot of developers in the incremental games community - the genre seems to draw them in, and convert a lot of players into developers. Let's explore the reasons why this genre appeals to developers.

Incrementals are Easy to Make

Compared to other genres, incrementals have quite low expectations. You don't need to make fancy art, or music, or lay things out nicely. If you can make a button and learn the few lines of code necessary to make a number go up, you can make an incremental. This low threshold makes the genre perfect for those who are actively learning to code and haven't developed any gamedev-related skills yet.

Additionally, unlike other genres incrementals are uniquely easy to implement in a normal web page - no need to worry about rendering sprites, moving them around, implementing physics, etc. New developers can just use HTML to add a button, and the game is now available in your browser. You don't need to choose an engine, have admin privileges, or hell for the dedicated you don't even need a computer - there are tools for web development that run in the browser itself, so you can technically use your phone if that's all you have.

Javascript is a perfectly viable language for making web games, whereas other genres are typically going to require using other more difficult languages to learn. There are countless javascript tutorials that start from 0 knowledge of programming, making it incredibly accessible to beginners.

Players are Easy to Find

Once you've finished your game and uploaded it on github pages or itch or just copied the link if you're using glitch or replit (all of which are easy to do), anyone can now play the game in their browser. This low barrier to entry has shown tremendous success in getting completely unknown developers to have thousands of plays.

The incremental games community, which mostly centers around r/incremental_games, is always looking for new games and tends to flood any new ones posted with initial players.

Having your games be played can be incredibly motivating, and the community makes it quite clear that you can expect players to play your game. These communities - both for incremental games in general as well as game-specific communities - tend to be very developer friendly as well. A lot of the developers know each other, and welcome new developers with open arms, often with dedicated channels for programming help and discussions.

Monetization

I'd like to clarify that everything I've said above mainly applies to web-based incrementals. Incremental games are also incredibly popular on mobile, but with a much different culture and community. Many mobile gamers will still participate in the web-focused community for the culture. This web-focused community has a culture that has been criticized for being "anti-monetization". Ads, IAPs, and similar forms of monetization are often criticized, mainly due to the abundance of completely non-monetized games available from hobbyist developers. There are exceptions, like paid games often being considered fine, like Increlution or Stuck in Time, or donation ware games like kittens game, but even popular games that have IAP see some level of regular criticism, like NGU Idle, Idle Skilling, or Idle Pins. A large part of this can be explained by the community being hyper-aware of the addictive) nature of this genre and its susceptibility to exploiting players.

On mobile, however, monetization is the norm and expected. If an incremental game is available on mobile, it almost certainly will be monetized, and mobile players are aware and accepting of that. Mobile incremental games, due to their addictive nature, tend to make a lot of money. It's very lucrative, and therefore these games are quite abundant on mobile storefronts.

+ \ No newline at end of file diff --git a/guide-to-incrementals/ludology/appeal-gamers/index.html b/guide-to-incrementals/ludology/appeal-gamers/index.html index 9c1bbc7f9..e0e67d0a9 100644 --- a/guide-to-incrementals/ludology/appeal-gamers/index.html +++ b/guide-to-incrementals/ludology/appeal-gamers/index.html @@ -6,14 +6,14 @@ Guide to Incrementals/Appeal to Players | The Paper Pilot - + - + - - - + + + @@ -51,10 +51,10 @@ -
Skip to content

Guide to Incrementals/Appeal to Players

2166 words, ~12 minute read. Planted +

Skip to content

Guide to Incrementals/Appeal to Players

2166 words, ~12 minute read. Planted . Last tended to -.


Referenced by:Incremental SocialKronos

This is something that has been discussed and analyzed by many people, and to some extent, I feel like everything that can be said on the topic already has. However, a lot of these analyses are from the perspective of those with not as much experience and involvement within the genre as I'd argue would be necessary for a fully contextualized answer. I'm interested in ludology and part of that includes interpreting games as art, and to that end what constitutes a game, let alone a "good game". Incremental games are oft criticized, unfairly in my biased opinion, of not even constituting games, such as was posited by this polygon article.

Numbers Going Up

This is a very common response to why people enjoy incremental games, although it's not one I find compels me personally, and I suspect it might be a stand-in for progression) or Guide to Incrementals/What is Content?. But reportedly, some people do just like seeing big numbers. I must reiterate I suspect the actual cause is seeing big numbers in context though - if you start at 1e1000 of a currency and get to 1e1001, that isn't going to feel as satisfying as going from 1e10 to 1e100, and in any case, I don't think a button that just adds a zero to your number will feel quite satisfying - I believe its the sense of having made progress, and comparing where you are to where you started and feeling like you've earned your way here that is enjoyable.

Progression

I think a strong sense of progression is seen as very enjoyable to many players of all sorts of genres - engine builder board games, RPGs, rogue_lites_, etc. Incremental games tend to have an extremely exaggerated sense of progression, which makes them very appealing.

Meta-progression is when games have some sort of progression that persists when other progress gets lost - for example, upgrades that persist between runs of a roguelite game. These are common mechanics in incremental games - in fact, its not uncommon to have multiple of these reset mechanics nested on top of each other, each with their own meta-progression. These are satisfying to players, although they can be a bit controversial. These mechanics can often be seen as an optional crutch, and in roguelite games, players often challenge themselves to win without any meta progression. Essentially these challenges argue that meta-progression de-emphasizes player skill by replacing it with time served. Incremental games, through their exaggerated progression, eschew that possibility though - they make it impossible to beat without the meta progression systems, as the meta-progression becomes an entire chapter of the gameplay. I'd argue this does not detract from the game, however, and is actually a part of what makes incremental games, and roguelikes, enjoyable to many players: meta-progression augments the increases in skill the player is naturally gaining as they play. In effect, it's not replacing the skill increase, but exaggerating it to make it feel more real to the player.

Effortlessness

Incremental games are so easy, a lot of them even have you progress while you're not playing! Part of the appeal is being able to feel like you're making progress while doing something actually productive - multitasking, in a way. In this sense, the game is more of a fidget toy - not something to think hard about and play actively, but something to click a few buttons every so often while you're paying attention to a lecture or studying or working. Of course, not all incremental games lend themselves to being played this way - it's specifically "idle" games that work like this. These are games that take an incredibly long amount of time to see all the content, stretching it as thin as possible, but they aren't expecting you to be sitting at your device playing it the entire time. They expect you to leave and come back later to make a bit of progress and repeat the cycle.

If you look at the higher-level play of most games, you'll see them perform difficult feats with ease and speed. They'll achieve a "flow state" that takes all their knowledge and experience of the game and uses it to play the game as instinctively as possible. It's incredible to watch things like Slay the Spire speed runs or competitive DDR-likes. I'd argue the goal of a lot of games with a competitive scene is to get so good that the game becomes effortless. In that sense, a game that allows you to reach that point earlier isn't any less legitimate, but rather lowers the barrier to entry by allowing more people to get "really good" at the game. And to be clear, (most) incremental games aren't trivially easy - they, and to an extent, every game will have some level of learning and improvement over time.

Addiction

A lot of these reasons for why incremental games appeal may have reminded you of why gambling appeals to people, particularly those prone to addiction. Indeed, incremental games are quite often criticized for their similarity to a skinner box. Some have gone as far as to say incremental games as a genre are commenting that all games are skinner boxes). The argument goes that some games are not fun, but rather condition players into continuing to play without actually getting anything from the experience. When tied to real-world money this is seen as predatory, and to a lesser extent, even free games may be feeding the addictive sides of people and making them more prone to seek out gambling or micro-transaction heavy games.

While incremental games can be fun and even healthy in certain contexts, they can exacerbate video game addiction more than other genres. If you feel like playing incremental games is taking priority over other things in your life, or manipulating your sleep schedule, it may be prudent to seek help. See r/StopGaming for resources.

Since incremental games are often built on extrinsic motivations in the form of progression systems, it's hard to argue whether players continue to play because they are enjoying the gameplay, or if they are just conditioned to keep doing it because the game keeps rewarding them. Unfortunately, it can often feel like it's the latter, as there isn't typically anything compelling about the "gameplay" of clicking a button and waiting. There may be a significant overlap between those who enjoy incremental games and those who are most prone to addiction, and there are often posts on r/incremental_games about someone either struggling with or overcoming video game addiction.

Strategy

Incremental games could be considered a subset of strategy games), and inherit the appeals of strategy games. This includes the appeal of feeling like you've found a good solution to a puzzle, or that you're learning more about the game and are improving at making decisions within it.

Note that strategy games are not all the same difficulty, as well. Cookie Clicker is probably easier than Starcraft 2 (although late game may beg to differ). Plenty of incremental games can be used as evidence that "easier" strategies may have their separate appeal to harder strategy games - players like to feel smart and that they figured the game out and have optimized or mastered it, and the game being easier doesn't detract from that sense of accomplishment as much as it allows more and more users to be able to reach the point where they gain that sense.

Avoiding Staleness

Incremental games tend to have "paradigm shifts", where the gameplay changes in a meaningful way at various times throughout the progression of the game. These upset and change the gameplay loop, which helps keep them from stagnating. This constant "freshness" to the gameplay can keep players engaged for longer, compared to a game with a repetitive and static gameplay loop.

Good Game Design

Incremental games tend to show their game design "plainly", so it's more readily apparent if a game has good game design while playing, even if you're not looking for it. While different players have different preferences and might enjoy different types of games more than others, there are underlying good and bad game design principles that players will notice the effects of. To be clear, this isn't talking about stuff like big numbers being enjoyable, where I can comfortably agree to disagree with other players. They don't intrinsically make my experience better, but I'm aware of those for whom it does and I won't argue against their feelings. However, the game designer in me does feel like there are some extremely clear-cut examples of good and bad game design philosophies.

Let's start by giving an example of a mechanic I think can be easily and strongly argued is good game design. There are of course many examples, but a personal favorite of mine is how DOOM encourages aggressive gameplay by linking health drops to melee attacks. It has an intended experience it's trying to give the player - immersing themselves as DOOM guy, who would not hide behind cover when low on health - and this mechanic does a great job at encouraging and effectively teaching players to behave properly. This is in sharp contrast to shooters like Call of Duty, which have you regen health passively, encouraging players to hide behind cover and wait after getting hit. Note that I'm not arguing CoD is poorly designed, as the games have different intended experiences. I'm specifically praising DOOM for having a mechanic that does a good job at ensuring the player has that intended experience.

To contrast with an example I think is bad game design, let's talk about shields in souls-likes. This is a bit of a famous example, and I highly recommend this video essay which spends quite a good bit of time on this topic. Essentially, the argument boils down to players of earlier games in the souls games using shields too much - playing slowly, conservatively, and ultimately having less fun. Players wanted to feel safe, so they ended up playing in a way that ruined the experience for them. The developers solved this by removing shields, apart from an intentionally bad one effectively mocking the playstyle, and it did its job at getting players to play more aggressively, and often have more fun.

To bring the conversation back to incrementals, I'm incredibly opinionated on what makes a good incremental game, which I'll discuss in the game design section. Suffice it to say, incremental games rely more on good game design than other genres, due to not having much to distract from bad game design. This helps (although imperfectly - gamers are a bit too tolerant of bad game design!) well-designed games rise to the top within the genre.

Artistic Merit

The discussion of whether video games are art has resulted in a pretty universal "yes, they are", but with some games the argument may still crop up. The reason why Incremental games are sometimes questioned is due to their perceived lack of complexity. However, even setting aside the fact that if players are having fun then it's not time wasted, I think games can have artistic merit that supersedes the necessity of having (any / engaging / "deep") gameplay. Incremental games are no less legitimate of a game or the "art" label because of any lack perceived lack of depth. For what it's worth, most art can be consumed with more ease than any video game - any painting, movie, sculpture, etc.

A lot of incrementals have a narrative context that can similarly qualify them as art. Cookie Clicker is, as has been pointed out numerous times before, commenting on excess and increasing production beyond any reasonable limits - devolving into increasing production for its own sake. Indeed, a lot of incremental games are written to comment upon various concepts like capitalism or tropes in games, as discussed when defining Incrementals). However, I'd like to argue most incremental games are still art, even without any narrative context. "Art" as a concept is pretty nebulous already, but I personally like those who define it as an act of expression more than any physical result. The creator and the context within which they created the art, and any meaning they put into it, are all relevant and a part of the art itself. Most incremental games have artistic merit from things like why the creator made it, why they chose to make it an incremental game, and why they made any particular design decision. Hell, even if you play through an entire incremental game without a single thought or feeling, that very fact it elicited nothing can itself be artistic merit!

I'm not an art major, and I may be taking a somewhat extreme take on what is art and what has artistic merit, but I'd argue the overall point stands that games, and incremental games specifically, can have artistic merit, which appeals to many gamers.

- +.


Referenced by:Incremental SocialKronos

This is something that has been discussed and analyzed by many people, and to some extent, I feel like everything that can be said on the topic already has. However, a lot of these analyses are from the perspective of those with not as much experience and involvement within the genre as I'd argue would be necessary for a fully contextualized answer. I'm interested in ludology and part of that includes interpreting games as art, and to that end what constitutes a game, let alone a "good game". Incremental games are oft criticized, unfairly in my biased opinion, of not even constituting games, such as was posited by this polygon article.

Numbers Going Up

This is a very common response to why people enjoy incremental games, although it's not one I find compels me personally, and I suspect it might be a stand-in for progression) or Guide to Incrementals/What is Content?. But reportedly, some people do just like seeing big numbers. I must reiterate I suspect the actual cause is seeing big numbers in context though - if you start at 1e1000 of a currency and get to 1e1001, that isn't going to feel as satisfying as going from 1e10 to 1e100, and in any case, I don't think a button that just adds a zero to your number will feel quite satisfying - I believe its the sense of having made progress, and comparing where you are to where you started and feeling like you've earned your way here that is enjoyable.

Progression

I think a strong sense of progression is seen as very enjoyable to many players of all sorts of genres - engine builder board games, RPGs, rogue_lites_, etc. Incremental games tend to have an extremely exaggerated sense of progression, which makes them very appealing.

Meta-progression is when games have some sort of progression that persists when other progress gets lost - for example, upgrades that persist between runs of a roguelite game. These are common mechanics in incremental games - in fact, its not uncommon to have multiple of these reset mechanics nested on top of each other, each with their own meta-progression. These are satisfying to players, although they can be a bit controversial. These mechanics can often be seen as an optional crutch, and in roguelite games, players often challenge themselves to win without any meta progression. Essentially these challenges argue that meta-progression de-emphasizes player skill by replacing it with time served. Incremental games, through their exaggerated progression, eschew that possibility though - they make it impossible to beat without the meta progression systems, as the meta-progression becomes an entire chapter of the gameplay. I'd argue this does not detract from the game, however, and is actually a part of what makes incremental games, and roguelikes, enjoyable to many players: meta-progression augments the increases in skill the player is naturally gaining as they play. In effect, it's not replacing the skill increase, but exaggerating it to make it feel more real to the player.

Effortlessness

Incremental games are so easy, a lot of them even have you progress while you're not playing! Part of the appeal is being able to feel like you're making progress while doing something actually productive - multitasking, in a way. In this sense, the game is more of a fidget toy - not something to think hard about and play actively, but something to click a few buttons every so often while you're paying attention to a lecture or studying or working. Of course, not all incremental games lend themselves to being played this way - it's specifically "idle" games that work like this. These are games that take an incredibly long amount of time to see all the content, stretching it as thin as possible, but they aren't expecting you to be sitting at your device playing it the entire time. They expect you to leave and come back later to make a bit of progress and repeat the cycle.

If you look at the higher-level play of most games, you'll see them perform difficult feats with ease and speed. They'll achieve a "flow state" that takes all their knowledge and experience of the game and uses it to play the game as instinctively as possible. It's incredible to watch things like Slay the Spire speed runs or competitive DDR-likes. I'd argue the goal of a lot of games with a competitive scene is to get so good that the game becomes effortless. In that sense, a game that allows you to reach that point earlier isn't any less legitimate, but rather lowers the barrier to entry by allowing more people to get "really good" at the game. And to be clear, (most) incremental games aren't trivially easy - they, and to an extent, every game will have some level of learning and improvement over time.

Addiction

A lot of these reasons for why incremental games appeal may have reminded you of why gambling appeals to people, particularly those prone to addiction. Indeed, incremental games are quite often criticized for their similarity to a skinner box. Some have gone as far as to say incremental games as a genre are commenting that all games are skinner boxes). The argument goes that some games are not fun, but rather condition players into continuing to play without actually getting anything from the experience. When tied to real-world money this is seen as predatory, and to a lesser extent, even free games may be feeding the addictive sides of people and making them more prone to seek out gambling or micro-transaction heavy games.

While incremental games can be fun and even healthy in certain contexts, they can exacerbate video game addiction more than other genres. If you feel like playing incremental games is taking priority over other things in your life, or manipulating your sleep schedule, it may be prudent to seek help. See r/StopGaming for resources.

Since incremental games are often built on extrinsic motivations in the form of progression systems, it's hard to argue whether players continue to play because they are enjoying the gameplay, or if they are just conditioned to keep doing it because the game keeps rewarding them. Unfortunately, it can often feel like it's the latter, as there isn't typically anything compelling about the "gameplay" of clicking a button and waiting. There may be a significant overlap between those who enjoy incremental games and those who are most prone to addiction, and there are often posts on r/incremental_games about someone either struggling with or overcoming video game addiction.

Strategy

Incremental games could be considered a subset of strategy games), and inherit the appeals of strategy games. This includes the appeal of feeling like you've found a good solution to a puzzle, or that you're learning more about the game and are improving at making decisions within it.

Note that strategy games are not all the same difficulty, as well. Cookie Clicker is probably easier than Starcraft 2 (although late game may beg to differ). Plenty of incremental games can be used as evidence that "easier" strategies may have their separate appeal to harder strategy games - players like to feel smart and that they figured the game out and have optimized or mastered it, and the game being easier doesn't detract from that sense of accomplishment as much as it allows more and more users to be able to reach the point where they gain that sense.

Avoiding Staleness

Incremental games tend to have "paradigm shifts", where the gameplay changes in a meaningful way at various times throughout the progression of the game. These upset and change the gameplay loop, which helps keep them from stagnating. This constant "freshness" to the gameplay can keep players engaged for longer, compared to a game with a repetitive and static gameplay loop.

Good Game Design

Incremental games tend to show their game design "plainly", so it's more readily apparent if a game has good game design while playing, even if you're not looking for it. While different players have different preferences and might enjoy different types of games more than others, there are underlying good and bad game design principles that players will notice the effects of. To be clear, this isn't talking about stuff like big numbers being enjoyable, where I can comfortably agree to disagree with other players. They don't intrinsically make my experience better, but I'm aware of those for whom it does and I won't argue against their feelings. However, the game designer in me does feel like there are some extremely clear-cut examples of good and bad game design philosophies.

Let's start by giving an example of a mechanic I think can be easily and strongly argued is good game design. There are of course many examples, but a personal favorite of mine is how DOOM encourages aggressive gameplay by linking health drops to melee attacks. It has an intended experience it's trying to give the player - immersing themselves as DOOM guy, who would not hide behind cover when low on health - and this mechanic does a great job at encouraging and effectively teaching players to behave properly. This is in sharp contrast to shooters like Call of Duty, which have you regen health passively, encouraging players to hide behind cover and wait after getting hit. Note that I'm not arguing CoD is poorly designed, as the games have different intended experiences. I'm specifically praising DOOM for having a mechanic that does a good job at ensuring the player has that intended experience.

To contrast with an example I think is bad game design, let's talk about shields in souls-likes. This is a bit of a famous example, and I highly recommend this video essay which spends quite a good bit of time on this topic. Essentially, the argument boils down to players of earlier games in the souls games using shields too much - playing slowly, conservatively, and ultimately having less fun. Players wanted to feel safe, so they ended up playing in a way that ruined the experience for them. The developers solved this by removing shields, apart from an intentionally bad one effectively mocking the playstyle, and it did its job at getting players to play more aggressively, and often have more fun.

To bring the conversation back to incrementals, I'm incredibly opinionated on what makes a good incremental game, which I'll discuss in the game design section. Suffice it to say, incremental games rely more on good game design than other genres, due to not having much to distract from bad game design. This helps (although imperfectly - gamers are a bit too tolerant of bad game design!) well-designed games rise to the top within the genre.

Artistic Merit

The discussion of whether video games are art has resulted in a pretty universal "yes, they are", but with some games the argument may still crop up. The reason why Incremental games are sometimes questioned is due to their perceived lack of complexity. However, even setting aside the fact that if players are having fun then it's not time wasted, I think games can have artistic merit that supersedes the necessity of having (any / engaging / "deep") gameplay. Incremental games are no less legitimate of a game or the "art" label because of any lack perceived lack of depth. For what it's worth, most art can be consumed with more ease than any video game - any painting, movie, sculpture, etc.

A lot of incrementals have a narrative context that can similarly qualify them as art. Cookie Clicker is, as has been pointed out numerous times before, commenting on excess and increasing production beyond any reasonable limits - devolving into increasing production for its own sake. Indeed, a lot of incremental games are written to comment upon various concepts like capitalism or tropes in games, as discussed when defining Incrementals). However, I'd like to argue most incremental games are still art, even without any narrative context. "Art" as a concept is pretty nebulous already, but I personally like those who define it as an act of expression more than any physical result. The creator and the context within which they created the art, and any meaning they put into it, are all relevant and a part of the art itself. Most incremental games have artistic merit from things like why the creator made it, why they chose to make it an incremental game, and why they made any particular design decision. Hell, even if you play through an entire incremental game without a single thought or feeling, that very fact it elicited nothing can itself be artistic merit!

I'm not an art major, and I may be taking a somewhat extreme take on what is art and what has artistic merit, but I'd argue the overall point stands that games, and incremental games specifically, can have artistic merit, which appeals to many gamers.

+ \ No newline at end of file diff --git a/guide-to-incrementals/ludology/content/index.html b/guide-to-incrementals/ludology/content/index.html index 9d747397e..123b53fc6 100644 --- a/guide-to-incrementals/ludology/content/index.html +++ b/guide-to-incrementals/ludology/content/index.html @@ -6,14 +6,14 @@ Guide to Incrementals/What is Content? | The Paper Pilot - + - + - - - + + + @@ -51,10 +51,10 @@ -
Skip to content

Guide to Incrementals/What is Content?

2272 words, ~12 minute read. Planted +

Skip to content

Guide to Incrementals/What is Content?

2272 words, ~12 minute read. Planted . Last tended to -.


Referenced by:Incremental SocialKronos

If you've been in the incremental games community for any amount of time, you'll quickly find the number one thing players want is content. They want as much of it as possible! The most popular incremental games have tons of content, so they just keep stretching on and on and on, introducing mechanic after mechanic, and players love it. In fact, players seem to value the amount of content over the quality of any specific content. However, there's a bit of a lack of understanding concerning what content is, and I'd like to explore what counts as content, and how we measure it. As a baseline definition, I think "content" can just be described as the parts of the game that engage the player, but to truly understand it we need to contextualize what that means and how it affects the gameplay experience.

To clarify the purpose of this page, my goal is not to get (too) nitpicky or to attack games with "low content". There's nothing wrong with short / low-content games - I'm quite a big fan of those games myself! This is mostly targeted toward those who ask for content and settle for "long" games, and those who want to provide content but want to make sure they're not just artificially inflating the game. Ultimately, I suppose the goal is to just reduce the amount of artificially inflated content for the sake of having a "longer" game.

Interaction

I think it should be a fairly non-controversial opinion that time spent solely waiting should not count towards content. That is not including the time reading various effects or making decisions in your head, but rather time spent waiting for a condition to be met so you can re-engage with the game.

That is not to say games should necessarily try to minimize this time. Plenty of games lead towards more infrequent interaction and still get popular. In fact, these games appeal to many gamers who want to have something to check up on in between bursts of working on some other activity. These games seem to have fallen slightly out of fashion amongst modern incremental games, but they're still fully valid. The point I'm trying to make here is just that this time is not content. As an extreme example, a game with no interactions and just a counter that goes up every second could safely be said to have 0 content beyond the time it takes to understand what's going on. If it has a list of "goals" to hit, then the time understanding those goals and a short time after achieving each one could be considered content, but not the idle times in between.

Let's take a look at the opposite end of the spectrum - interaction that is so frequent as to become mindless. This is any mechanic where you need to spam-click something to progress. This may be a more controversial take, but I do not believe this constitutes content either. It does not engage the player, because each consecutive click blends together and they do not individually change the gameplay experience. That is to say, a single click and 100 clicks are not meaningfully different in terms of engaging the player. I'd go as far as to say clicking 100 times would be actively worse, as it's artificially delaying the next piece of actual content, alongside the issues of accessibility and potentially causing RSI.

Repeatable Purchases

Imagine an entity in a game that you can purchase multiple times, each time it performs the same thing but for a higher cost. These are incredibly common, from the buildings in cookie clicker to the units in swarm sim to the IP and EP multipliers in antimatter dimensions. However, how much content is each specific purchase? Is it content beyond the first purchase? Does it have diminishing returns? What if you are oscillating between two different repeatable purchases? How much content is lost when you automate) away a repeatable purchase?

I don't want to take too harsh a stance against repeatable purchases. They're useful tools and can be used in a myriad of interesting ways. I feel they do become "stale" or less meaningful content over time, and this happens exponentially quickly the more frequently it can be purchased. A classic example that I believe goes too far is the IP/EP multipliers in Antimatter Dimensions. I would go as far as to say they are a chore and do not provide any meaningful content after you've bought them a couple of times. It's a method for inflating numbers (effectively making every OOM a 5x step instead of 10x), that punishes the player progression-wise whenever they forget to max it again, and eventually gets automated away as a reward to the player for making enough progress.

Just to voice the other side of this argument, Acamaeda defended the IP multiplier as giving the player a "good" upgrade every OOM. I can understand that to a point and need to clarify I'm mainly criticizing IP/EP multipliers after they've been introduced for a while. In fact, I would defend the multipliers for a short while after they're introduced using the same logic I would use to defend normal dimensions as repeatable purchases, at least pre-infinity. There's "content" to be had in looking at what dimensions will become affordable next, and then choosing which to buy amongst those. The IP/EP multipliers, early into infinity or eternity respectively, provide another option that gets put into that mental queue of things to buy with each OOM reached - although the optimal order is often quite trivial and not particularly engaging.

The IP/EP multipliers are not the only repeatable purchase in antimatter dimensions I take offense to. The time dimensions are also a series of repeatable purchases, that are all so similar and static that it doesn't take long before you never need to put any thought into buying them, how much you're buying at once, or the order you buy them in - you just press max all and move on. The entire tab could've been just the max all button and it would not have made a difference beyond the start of the eternity layer. The normal dimensions technically have this problem as well, but since you're constantly getting antimatter the order feels like it has a larger impact and it's more meaningful content, right up until they're automated away. Infinity dimensions are a compromise between the two, so I'm highlighting time dimensions here as the most egregious.

Following Instructions

We're getting more and more controversial as we go along! Let's talk about how linear content is not content now (in some circumstances). A trend in incremental games is adding difficulty by adding a web of effects that abstract the true change you can expect from any specific purchase or decision you make. If a game is both linear and sufficiently abstracts the effect of player decisions, then the player will no longer be engaging with the content - they'll simply be clicking on things as they become available. This isn't necessarily a bad thing, as plenty of players don't mind this style of gameplay, but I'd argue once you reach a point where players don't bother reading the effects, those interactions are no longer truly content. Note that unlike the previous qualifiers mentioned, this qualifier is based on the player, and therefore subjective. In effect, it's a spectrum where the more complicated the web of effects becomes, the more likely it is to disengage the player.

This over-complicatedness leading to disengaging the player can also happen from non-linear gameplay. If the web of effects becomes sufficiently complicated and finding the optimal progression route too time-consuming to discover, players will seek out guides from other players who've completed the game. The second they do this, the game effectively becomes linearly following the instructions of the guide and all the above criticisms apply. Similarly to as before, though, this is a spectrum and not everyone will seek out a guide at the same level of difficulty.

Automation

Automation is a staple of the genre, but it has certain implications for the design of the game. Why, when new content is introduced, must the older content be automated away - why is it a chore and it feels rewarding to not have to do it again? Why does the new mechanic have such appeal if we know it too will just be automated away later on, and we'll be happy when that happens? It honestly begs the question of why this framework of introducing content and automating the old content is even enjoyable - and nearly nonexistent in other genres. You're not going to reach a point in a platformer game where they just automate the jumping part - that's the core mechanic! Instead, platformers either add new mechanics that build on the core mechanic or at least re-contextualize the core mechanic. However, in incremental games new content very frequently means replacing older content, as opposed to augmenting it.

Admittedly, the above paragraph ignores the obvious answer that separates incremental games in this regard. These mechanics become chores as their frequency increases. The frequency increases to give a sense of progression, and automation is seen as a reward because it now manages what was becoming unmanageable. The new content then comes in and continues the loop to give a stronger sense of progression. That's all good and a fine justification for automating content instead of building upon the base mechanic. It's also much easier to design, as each layer essentially lets you start over instead of needing to think of ideas that conform to the original core mechanic.

So, what's the problem? Even if this trend is justified and easy to implement, there are some other effects it has on the game design. First off, and this is probably a neutral point, incremental games with this cycle of replacing old mechanics with new ones trend towards more and more abstract and further away from any narrative throughline as they add layers. There are only so many justifications for resetting progress, so if a game wants to have several of these layers they're inevitably going to become generic or increasingly loosely associated with the original content. It's most unfortunate, in my opinion when an interesting or innovative core mechanic gets fully automated once a generic "prestige" layer is unlocked.

A recent example is Really Grass Cutting Incremental, an incremental game about cutting grass (although I'm really criticizing the Roblox game it's based on). Except, it doesn't continue to be about cutting grass. After you buy enough upgrades to increase your grass cutting and level up sufficiently you "prestige", an abstract term that in this case means you reset all your progress to get some currency to buy upgrades that do the same things as the original upgrades, but these won't reset on future prestiges. You'll eventually be able to "crystallize", which means you reset all your progress to get some currency to buy upgrades that do the same things as the original upgrades (and a couple of new ones) and won't reset on future crystallizes. Fine. You'll progress a bit, complete some challenges, and finally get to... grasshop? Grasshopping is this mechanic where you reset all your progress to get some resource that isn't for buying upgrades - this time you just unlock different modifiers on everything based on their amount. You may have gotten the point by now, but there are also "steelie" resets which give you steel for some reason, before unlocking a factory with various machines - none of which are directly tied to cutting grass, and start gathering things like oil and reset for rocket parts and reset to go to space and so on and so on. Throughout all of this there is absolutely no narrative justification or throughline for the direction the game is going, or why cutting grass is still relevant when we're collecting things like rocket parts. I may be going a little hard on GCI, but it is far from alone.

Ending the Game

Incremental games do not often have a planned out narrative or ending,, such that each content update is approached as its own unit of narrative and gameplay. This prevents content updates from wrapping up the game nicely - it always has to leave something open for another content layer; be it another mechanic, reset layer, etc. This cycle will continue until the updates just stop, at which point the game will just have an unsatisfying conclusion that will never get the next thing it was supposed to be leading into. This reminds me of a Leonardo Da Vinci quote about how Art is Never Complete:

Art is never finished, only abandoned. - Leonardo Da Vinci

For what its worth, there are exceptions here (including several of My Projects). I believe this practice is actually fairly reasonable, considering how many incremental game developers are learning game design and programming - keeping the scope small and expanding if it still interests you is a great way to keep learning without letting things like perfectionism or sunk cost fallacies get in the way.

Tips for Developers

If you're a developer, by this point you should have a pretty decent idea of how to create "true" content in your game. Here are some other specific tips I'd suggest:

An upgrade that simply unlocks another upgrade trivially isn't content. However, many games have an upgrade that just unlocks a feature, which then has a wait or other requirements before it can be used. Try to make sure when you unlock a feature, there is immediately something to do with the feature - for example, perhaps give them a small amount of the new currency it unlocks, if applicable.

If you don't have a large web of effects, and can definitively say the impact of a purchase is to multiply the gain of the cost currency by N, and the next purchase costs N times the amount of that same currency, then this purchase effectively made no difference and it may have made more sense to just go directly to the next upgrade. That said, having effects based on things like the number of purchases made will quickly invalidate this tip.

- +.


Referenced by:Incremental SocialKronos

If you've been in the incremental games community for any amount of time, you'll quickly find the number one thing players want is content. They want as much of it as possible! The most popular incremental games have tons of content, so they just keep stretching on and on and on, introducing mechanic after mechanic, and players love it. In fact, players seem to value the amount of content over the quality of any specific content. However, there's a bit of a lack of understanding concerning what content is, and I'd like to explore what counts as content, and how we measure it. As a baseline definition, I think "content" can just be described as the parts of the game that engage the player, but to truly understand it we need to contextualize what that means and how it affects the gameplay experience.

To clarify the purpose of this page, my goal is not to get (too) nitpicky or to attack games with "low content". There's nothing wrong with short / low-content games - I'm quite a big fan of those games myself! This is mostly targeted toward those who ask for content and settle for "long" games, and those who want to provide content but want to make sure they're not just artificially inflating the game. Ultimately, I suppose the goal is to just reduce the amount of artificially inflated content for the sake of having a "longer" game.

Interaction

I think it should be a fairly non-controversial opinion that time spent solely waiting should not count towards content. That is not including the time reading various effects or making decisions in your head, but rather time spent waiting for a condition to be met so you can re-engage with the game.

That is not to say games should necessarily try to minimize this time. Plenty of games lead towards more infrequent interaction and still get popular. In fact, these games appeal to many gamers who want to have something to check up on in between bursts of working on some other activity. These games seem to have fallen slightly out of fashion amongst modern incremental games, but they're still fully valid. The point I'm trying to make here is just that this time is not content. As an extreme example, a game with no interactions and just a counter that goes up every second could safely be said to have 0 content beyond the time it takes to understand what's going on. If it has a list of "goals" to hit, then the time understanding those goals and a short time after achieving each one could be considered content, but not the idle times in between.

Let's take a look at the opposite end of the spectrum - interaction that is so frequent as to become mindless. This is any mechanic where you need to spam-click something to progress. This may be a more controversial take, but I do not believe this constitutes content either. It does not engage the player, because each consecutive click blends together and they do not individually change the gameplay experience. That is to say, a single click and 100 clicks are not meaningfully different in terms of engaging the player. I'd go as far as to say clicking 100 times would be actively worse, as it's artificially delaying the next piece of actual content, alongside the issues of accessibility and potentially causing RSI.

Repeatable Purchases

Imagine an entity in a game that you can purchase multiple times, each time it performs the same thing but for a higher cost. These are incredibly common, from the buildings in cookie clicker to the units in swarm sim to the IP and EP multipliers in antimatter dimensions. However, how much content is each specific purchase? Is it content beyond the first purchase? Does it have diminishing returns? What if you are oscillating between two different repeatable purchases? How much content is lost when you automate) away a repeatable purchase?

I don't want to take too harsh a stance against repeatable purchases. They're useful tools and can be used in a myriad of interesting ways. I feel they do become "stale" or less meaningful content over time, and this happens exponentially quickly the more frequently it can be purchased. A classic example that I believe goes too far is the IP/EP multipliers in Antimatter Dimensions. I would go as far as to say they are a chore and do not provide any meaningful content after you've bought them a couple of times. It's a method for inflating numbers (effectively making every OOM a 5x step instead of 10x), that punishes the player progression-wise whenever they forget to max it again, and eventually gets automated away as a reward to the player for making enough progress.

Just to voice the other side of this argument, Acamaeda defended the IP multiplier as giving the player a "good" upgrade every OOM. I can understand that to a point and need to clarify I'm mainly criticizing IP/EP multipliers after they've been introduced for a while. In fact, I would defend the multipliers for a short while after they're introduced using the same logic I would use to defend normal dimensions as repeatable purchases, at least pre-infinity. There's "content" to be had in looking at what dimensions will become affordable next, and then choosing which to buy amongst those. The IP/EP multipliers, early into infinity or eternity respectively, provide another option that gets put into that mental queue of things to buy with each OOM reached - although the optimal order is often quite trivial and not particularly engaging.

The IP/EP multipliers are not the only repeatable purchase in antimatter dimensions I take offense to. The time dimensions are also a series of repeatable purchases, that are all so similar and static that it doesn't take long before you never need to put any thought into buying them, how much you're buying at once, or the order you buy them in - you just press max all and move on. The entire tab could've been just the max all button and it would not have made a difference beyond the start of the eternity layer. The normal dimensions technically have this problem as well, but since you're constantly getting antimatter the order feels like it has a larger impact and it's more meaningful content, right up until they're automated away. Infinity dimensions are a compromise between the two, so I'm highlighting time dimensions here as the most egregious.

Following Instructions

We're getting more and more controversial as we go along! Let's talk about how linear content is not content now (in some circumstances). A trend in incremental games is adding difficulty by adding a web of effects that abstract the true change you can expect from any specific purchase or decision you make. If a game is both linear and sufficiently abstracts the effect of player decisions, then the player will no longer be engaging with the content - they'll simply be clicking on things as they become available. This isn't necessarily a bad thing, as plenty of players don't mind this style of gameplay, but I'd argue once you reach a point where players don't bother reading the effects, those interactions are no longer truly content. Note that unlike the previous qualifiers mentioned, this qualifier is based on the player, and therefore subjective. In effect, it's a spectrum where the more complicated the web of effects becomes, the more likely it is to disengage the player.

This over-complicatedness leading to disengaging the player can also happen from non-linear gameplay. If the web of effects becomes sufficiently complicated and finding the optimal progression route too time-consuming to discover, players will seek out guides from other players who've completed the game. The second they do this, the game effectively becomes linearly following the instructions of the guide and all the above criticisms apply. Similarly to as before, though, this is a spectrum and not everyone will seek out a guide at the same level of difficulty.

Automation

Automation is a staple of the genre, but it has certain implications for the design of the game. Why, when new content is introduced, must the older content be automated away - why is it a chore and it feels rewarding to not have to do it again? Why does the new mechanic have such appeal if we know it too will just be automated away later on, and we'll be happy when that happens? It honestly begs the question of why this framework of introducing content and automating the old content is even enjoyable - and nearly nonexistent in other genres. You're not going to reach a point in a platformer game where they just automate the jumping part - that's the core mechanic! Instead, platformers either add new mechanics that build on the core mechanic or at least re-contextualize the core mechanic. However, in incremental games new content very frequently means replacing older content, as opposed to augmenting it.

Admittedly, the above paragraph ignores the obvious answer that separates incremental games in this regard. These mechanics become chores as their frequency increases. The frequency increases to give a sense of progression, and automation is seen as a reward because it now manages what was becoming unmanageable. The new content then comes in and continues the loop to give a stronger sense of progression. That's all good and a fine justification for automating content instead of building upon the base mechanic. It's also much easier to design, as each layer essentially lets you start over instead of needing to think of ideas that conform to the original core mechanic.

So, what's the problem? Even if this trend is justified and easy to implement, there are some other effects it has on the game design. First off, and this is probably a neutral point, incremental games with this cycle of replacing old mechanics with new ones trend towards more and more abstract and further away from any narrative throughline as they add layers. There are only so many justifications for resetting progress, so if a game wants to have several of these layers they're inevitably going to become generic or increasingly loosely associated with the original content. It's most unfortunate, in my opinion when an interesting or innovative core mechanic gets fully automated once a generic "prestige" layer is unlocked.

A recent example is Really Grass Cutting Incremental, an incremental game about cutting grass (although I'm really criticizing the Roblox game it's based on). Except, it doesn't continue to be about cutting grass. After you buy enough upgrades to increase your grass cutting and level up sufficiently you "prestige", an abstract term that in this case means you reset all your progress to get some currency to buy upgrades that do the same things as the original upgrades, but these won't reset on future prestiges. You'll eventually be able to "crystallize", which means you reset all your progress to get some currency to buy upgrades that do the same things as the original upgrades (and a couple of new ones) and won't reset on future crystallizes. Fine. You'll progress a bit, complete some challenges, and finally get to... grasshop? Grasshopping is this mechanic where you reset all your progress to get some resource that isn't for buying upgrades - this time you just unlock different modifiers on everything based on their amount. You may have gotten the point by now, but there are also "steelie" resets which give you steel for some reason, before unlocking a factory with various machines - none of which are directly tied to cutting grass, and start gathering things like oil and reset for rocket parts and reset to go to space and so on and so on. Throughout all of this there is absolutely no narrative justification or throughline for the direction the game is going, or why cutting grass is still relevant when we're collecting things like rocket parts. I may be going a little hard on GCI, but it is far from alone.

Ending the Game

Incremental games do not often have a planned out narrative or ending,, such that each content update is approached as its own unit of narrative and gameplay. This prevents content updates from wrapping up the game nicely - it always has to leave something open for another content layer; be it another mechanic, reset layer, etc. This cycle will continue until the updates just stop, at which point the game will just have an unsatisfying conclusion that will never get the next thing it was supposed to be leading into. This reminds me of a Leonardo Da Vinci quote about how Art is Never Complete:

Art is never finished, only abandoned. - Leonardo Da Vinci

For what its worth, there are exceptions here (including several of My Projects). I believe this practice is actually fairly reasonable, considering how many incremental game developers are learning game design and programming - keeping the scope small and expanding if it still interests you is a great way to keep learning without letting things like perfectionism or sunk cost fallacies get in the way.

Tips for Developers

If you're a developer, by this point you should have a pretty decent idea of how to create "true" content in your game. Here are some other specific tips I'd suggest:

An upgrade that simply unlocks another upgrade trivially isn't content. However, many games have an upgrade that just unlocks a feature, which then has a wait or other requirements before it can be used. Try to make sure when you unlock a feature, there is immediately something to do with the feature - for example, perhaps give them a small amount of the new currency it unlocks, if applicable.

If you don't have a large web of effects, and can definitively say the impact of a purchase is to multiply the gain of the cost currency by N, and the next purchase costs N times the amount of that same currency, then this purchase effectively made no difference and it may have made more sense to just go directly to the next upgrade. That said, having effects based on things like the number of purchases made will quickly invalidate this tip.

+ \ No newline at end of file diff --git a/guide-to-incrementals/ludology/definition/index.html b/guide-to-incrementals/ludology/definition/index.html index 5de797d18..9baf13c86 100644 --- a/guide-to-incrementals/ludology/definition/index.html +++ b/guide-to-incrementals/ludology/definition/index.html @@ -6,14 +6,14 @@ Guide to Incrementals/Defining the Genre | The Paper Pilot - + - + - - - + + + @@ -51,10 +51,10 @@ -
Skip to content

Guide to Incrementals/Defining the Genre

4048 words, ~22 minute read. Planted +

Skip to content

Guide to Incrementals/Defining the Genre

4048 words, ~22 minute read. Planted . Last tended to -.


Referenced by:Incremental SocialKronos

Video games are placed into genres for a variety of reasons. They can give a mental shorthand to set the player's expectations up, they can help a game market itself by its similarities to other, already popular games, and honestly, people just love categorization for its own sake. For this guide, it's important to define the genre so it is clear what games it's even talking about.

This poses a problem. Genres, being Social Constructs, suffer from the usual issues social constructs have of being vague and shifting over time. "Incremental", in particular, is a horribly vague way to define games. Most games have numbers going up in some form or another. We need a more specific definition - similar to how "strategy" can't just mean any game with any amount of strategy because that would be most games. What specifically differentiates incremental games from the rest?

"Incremental" implies it's a genre defined by a game mechanic, but all those game mechanics it could imply exist in many other games. Having a skill tree or upgrades doesn't make you incremental, and if a reset mechanic is all it takes then every roguelite would be an incremental as well. So clearly there's more to it than that - what makes an incremental an incremental?

I'd like to go over a couple of popular suggestions I've seen on defining the genre here. I have my personal preferences and will state them here, but I don't think there's a truly perfect answer.

BTW, if this article made you realize discourse around defining genres is actually a really interesting, even fascinating, topic, I recommend this video essay: Who Shot Guybrush Threepwood? | Genre and the Adventure Game.

Disclaimer: I mostly play incremental games on my computer, and my definitions will be heavily biased towards the games I'm familiar with.

Incrementals vs Idlers vs Clickers

Oftentimes people refer to this genre as idle games and/or clicker games. You'll even find a trend of oxymoronic game titles that contain both terms. "Incremental games" is the umbrella term both those terms fall under. However, I'd like to argue that not only is it better to just use the term "incremental games", but calling them "idle games" or "clicker games" is wrong. Almost universally, these terms are used interchangeably to refer to the same kind of game, where you start the game click spamming and eventually automate the process. Frankly, that kind of game deserves neither title, and the genre of incremental games has trended away from ever requiring click spamming, as it's a bad mechanic, anyways.

While these games do span a spectrum of how active it requires you to be, and sorting games by that metric can be useful for those looking for a particular experience, the borders of when an incremental game counts as an "idler" is too blurry for the term to be useful. "Incremental games" may not be a great descriptive term for the genre (hence this many thousands of words long page on defining what the genre even is), but it's strictly better than calling them "idler" or "clicker" games. This guide will always use the term "incremental games" unless quoting someone else, as it is the term you typically see on all modern games in the genre.

Incrementals as Parodies

Let's start with one of the most interesting definitions of incremental games. Incremental games appear to be distilled versions of games or genres, "revealing" the naked game design at the core of these games or genres not unlike how parodies comment upon their source material.

To understand what that means, think of how a casino uses skinner boxes to emotionally manipulate its customers to keep playing, but "dressing" up the skinner box with tons of stimuli to hide that ultimately the goal is to condition you into coming back compulsively. The idea that incremental games are parodies means taking the stance that at some level all games are similarly manipulating you, giving dopamine rewards in a way that manipulates you to keep playing while not necessarily giving you any value or fulfillment. Incremental games, then, are any games that plainly display the skinner box, and the manipulative core of the game, at the forefront of the experience.

While incremental games can be fun and even healthy in certain contexts, they can exacerbate video game addiction more than other genres. If you feel like playing incremental games is taking priority over other things in your life, or manipulating your sleep schedule, it may be prudent to seek help. See r/StopGaming for resources.

This "undressing" tends to go hand in hand with a reduced focus on aesthetics, often just printing the game state directly to the screen as text. This makes incremental games much easier to develop, particularly for those with programming skills but not art skills, but that's a tangent for why Incremental Games Guide to Incrementals/Appeal to Developers.

Before I continue, I'd like to make my stance clear that I love games and incremental games, and do not think they should be considered inherently bad or manipulative with the above logic. Skinner boxes are just a way of manipulating behavior via rewards. The games are still fun - that's the reward! I'd believe the real criticism here is that it is "empty fun", or "empty dopamine", that doesn't offer any additional value or sense of fulfillment. I don't think that's inherently bad in moderation, although it can become a problem if the game is manipulating you for profit-seeking, or if you play the game to the detriment of the other parts of your life.

Another interpretation of incremental games as parodies comes from several mainstream incremental games that are also parodies of capitalism, such as cookie clicker and adventure capitalist. It's a very common framework for incremental games to portray the ever-increasing numbers as an insatiable hunger for resources, like the ones observed within capitalism. Therefore, these games are used as evidence that the genre as a whole is about parody and commentary.

Popular videos on incremental games that portray the genre as parodies are Why Idle games make good satire, and how it was ruined. and Bad Game Design - Clicker Games. You may also be interested in this response to the latter video from a fan of incremental games: BadGood Game Design - Clicker Games.

I think that this definition ultimately ascribes a motive to the genre as a whole that only happens to apply to some of the more mainstream titles. There certainly are incremental games commenting on different things, including the genre itself as in the case of The Prestige Tree Classic, The Ascension Tree, or Omega Layers, but certainly not all. And of course, not all games that comment on something or parody something are incremental games! Additionally, a very large majority of incremental games are mobile games using these manipulative strategies to get players to spend as much money as possible - hell, Adventure Capitalist is ostensibly a critique on capitalism but features microtransactions and gameplay that manipulates you into buying them! These profit-seeking incremental games certainly belong within the genre but are hardly parodies when they too use manipulation to serve their interests. Also, from my own anecdotal experience, those who use this definition seem to do so from a fairly surface-level familiarity with the genre, and often in the context of criticizing the genre or the fans thereof.

Incrementals as NGU

Another broad definition often used is that incremental games are games where the focus of the game is "numbers going up". This definition proposes that other genres simply use increasing numbers as a means to an end, but incremental games uniquely only care about the numbers themselves going up. Put another way, it implies there should be no narrative justification for the numbers going up other than "why shouldn't they be going up?"

While this definition is common because it feels easy to understand, it is difficult to formally define. Often phrases are used to describe games using this framework, such as having an "exaggerated sense of progression" or "big" numbers. These terms are vague and don't demonstrate an actual threshold between non-incrementals and incrementals. Most games have a sense of progression, so when is it "exaggerated"? How big are "big" numbers? Most notably, RPGs that are typically not considered incrementals will often pass this definition.

Additionally, a lot of incrementals tend to have some theme guiding the gameplay, or at least the names of mechanics. This makes the line blurred between when numbers are going up for their own sake versus for a contextual reason. I believe this point is best illustrated that, while most RPGs are not considered incremental games, there is a sub-genre of "incremental RPGs" that typically relates to RPGs that perform combat automatically. This definition of incremental games does not support RPGs and "incremental RPGs" being on distinct sides of the line if the only difference between them is manual vs automatic combat.

Incrementals as Strategies

This is a rarer interpretation, but there are similarities between incremental games and strategy games, implying incrementals might just be a sub-genre of strategy games. By this approach, incremental games would be defined by their relation to strategy games, and how they involve player strategy. Incremental games are often large optimization problems - above all else, the actual gameplay the player is performing is deciding what to do next. The consequences of wrong decisions are typically more lenient in incremental games - such as just not making optimal progress - but they certainly get complex.

So if we accept the premise that incrementals could fall under strategy, we still need to define what makes a strategy game an incremental versus some other strategy sub-genre. This is a bit tricky due to one particular sub-genre of strategy games: Factory Builders.

Factory builders, such as Factorio or Satisfactory, are games about gaining ever increasing resources, optimizing production, and expanding more and more. That... sounds pretty similar, doesn't it? In fact, there's been some debate on whether factory builders would fall under the "incremental" umbrella. I think it's safe to say the two are certainly related, and probably have quite a bit of overlap in playerbase.

Roguelites as Incrementals?

Earlier on, I mentioned reset mechanics shouldn't be used in the definition because that could make all roguelites incrementals... But what if it does? A lot of incrementals can be described as games with a strong sense of progression, often with layers of meta-progression. Roguelites fit that bill to a T. What would make roguelites not incremental? I honestly don't think there's a good explanation here, but many fans of incremental games will state they do believe the two genres to be unrelated, even if there's a significant overlap between their player bases due to having similar appealing traits.

At this point, it'd be appropriate to consider what part of the definition of roguelites precludes them from also being incrementals, but that reveals a new problem: What are roguelites? They're usually defined as rogue_likes with meta-progression, but that just pushes the problem back a step: Incrementals aren't the only genre to have difficulties defining themselves, it seems! Roguelikes are another genre where the community argues over the formal definition of their genre, although that means we can borrow from their process of coming to a consensus, and maybe come across a viable definition for incremental games.

The Berlin Interpretation

By far the most popular way of defining roguelikes is the "Berlin Interpretation", which acknowledged the diversity of games within the genre and argued the definition should not be based on any ideals about what the genre ought to be, but rather defined by "its canon". They argued there are a handful of games that can be used to define the canon for roguelikes, and from those games, a list of factors can be derived to determine a game's "roguelikeness". The more factors a game has, the more of a roguelike it is. This strategy is very lenient, allowing a game to not present any specific factor so long as it shows enough, and accounts for the blurriness of any genre definition by not explicitly stating how many factors a game must have to qualify as a definite roguelike.

I believe this strategy for defining genres can be applied to other genres as well. A handful of games can be argued to be the incremental games canon, and a list of factors derived from them can be used to judge any game based on its "incrementalness". I'll propose such a canon and list of factors here, but by no means should it be considered the end-all-be-all.

Note: The "Temple of the roguelike", an authority within the genre, has since replaced the Berlin Interpretation with a new set of factors here: https://blog.roguetemple.com/what-is-a-traditional-roguelike/

A Modern Incremental Games Canon

Alright, time to get controversial. Up til now, I've been trying my best to stay objective and analytical, but now it's time to start making some opinionated decisions. I've created a list of games I think could be justified in making up a modern incremental games canon.

Before I mention the list, let's establish how I got to this list. First off, I'm really focusing on building a definition of the genre today, so I prefer modern games over traditional ones. A canon of culturally or historically significant titles to the genre would give a different list. Keep in mind the original Berlin interpretation (and the temple's update to it) were trying to define "traditional roguelikes", which is not my objective here. Building a canon that aims to trace the history of the genre is still valid and useful.

I'm also trying to ensure I pick a large breadth of incremental games, so I'm going to approach the list as a list of archetypes, with a single game to represent it but with other titles mentioned as other examples. This approach places each archetype as equally important, even if one only has a couple entries. Besides the impracticality of a canon that just includes every game, it'd be very biased towards games with large modding communities like Cookie Clicker or The Prestige Tree.

With all that behind us, here is a list of games I think could justifiably make up a Modern Incremental Games Canon:

  • Dodecadragons

    This game represents incremental games with many prestige layers that often have rapid resets and automate lower layers as more get unlocked. Other examples could also include The Prestige Tree, Really Grass Cutting Incremental Classic, Distance Incremental, or the massive modding community TPT has. A lot of the games I've personally worked on fall in this group, like Advent Incremental.

  • Evolve Idle

    This game represents incremental games with few prestige layers, very slow resets, and a focus on resource management. Typically involve some sort of worker allocation. Other examples would be Kitten's Game, Shark Game, or Magic Research.

  • (the) Gnorp Apologue

    This game represents incremental games with a central mechanic that gets added to by various other mechanics. All the mechanics remain relevant throughout the game, with different ones contributing most over time. Other examples include Nodebuster and To the Core. A lot of traditional games also fall in this archetype by having characters or buildings you level up, that each contribute additively to gaining the primary resources. These include Cookie Clicker, Clicker Heroes, and Realm Grinder. In a way, that makes the modern titles mentioned in this archetype the spiritual successors of those traditional games, and exemplifies how the genre has changed.

  • Idle Momentum

    This game represents incremental games that include polynomial growth as a central mechanic that is then built upon. Other examples include Antimatter Dimensions, Swarm Simulator, and Derivative Clicker.

  • Melvor Idle

    This game represents incremental games that are essentially a genre blend between incremental games and RPGs. Compared to other types of RPGs, these games have a focus on progressing while idle. Other examples would be IdleOn and a very large amount of mobile RPGs.

  • Stuck in Time

    This game represents incremental games that include a reset mechanic where there are pre-defined decisions being made during the course of the run. There's typically a concept of a playable character, whose actions are being "queued up" during a run, and these runs become longer or otherwise more productive as the game progresses. There are a lot of examples of this genre, including Cavernous II, Increlution, Progress Knight, Idle Loops, and Groundhog Life.

  • Universal Paperclips

    This game represents incremental games that involve several phases of completely distinct gameplay that fully replace the previous, called "paradigm shifts". Prestige layers are also often paradigm shifts, but this game represents paradigm shifts that are not reset mechanics but still transform the gameplay. Other examples would be Crank or A Dark Room. Spore would be an example that's not typically considered an incremental.

  • Unnamed Space Idle

    This game represents incremental games that focus on unlocking many different independent progression systems that boost each other, and all remain relevant throughout the course of the game. Other examples include NGU Idle, Anti-Idle, Idle Skilling, and Idle Wizard.

It may look like I've just shifted the problem down a level - rather than defining the genre, I'm now defining a bunch of sub-genres. However, the methods used here for defining the canon, and my attempt at ensuring a breadth of games by determining distinct archetypes, is just my approach. This list is additionally biased towards games I'm more familiar with, which will differ person to person. The only hard and fast rule is that every game on the list should be nearly universally accepted as an incremental game. So long as you do that, the factors should be relatively similar, although ofc individuals will still likely have small differences, as is the nature of socially constructed definitions.

Naturally this canon is a perpetual work-in-progress. I'm currently a bit uncertain about the distinctions between the evolve idle, melvor idle, and unnamed space idle archetypes. I could see those being rewritten as two or even a single archetype.

Unfolding

There are several related concepts mentioned in the canon - unfolding, prestige layers, and paradigm shifts. Unfolding is the umbrella term which includes the other two, and is clearly the highest possible value factor for an incremental. It's so common that for a while people referred to incrementals that exhibit this trait as "unfolding" games, to the point of trying to replace the term incremental due to their popularity.

There are many reasons for the appeal of unfolding mechanics. Oftentimes each mechanic builds on top of the existing mechanics, increasing the complexity of the game in steps so the player can follow along. In fact, sometimes the older mechanics will be entirely phased out (e.g. by automating them), so the complexity of the game remains roughly equal throughout the game. In any case, adding new mechanics regularly provides a sense of mystery, with the player anticipating what will happen next. They shake up the gameplay before it gets too stale - allowing the game to entertain for longer before the sense of Guide to Incrementals/What is Content? dissipates. Of the canon games selected above, I would argue every single one contains unfolding to some degree.

I should take a moment to say that while I'm hyping up this specific factor, we cannot just reduce the genre definition to "does it introduce new mechanics over time". Many games have paradigm shifts that are not incremental, so it's just an indicator of incrementalness. Every single canon game may show that it's common amongst incremental games, but could just as easily indicate that they're common in games in general.

High-Value Factors

I won't take as long to discuss the high and low-value factors, as you've already seen most of them brought up earlier on this page. As a reminder, a game does NOT need all of these to be an incremental game, but these are factors that each indicate a strong possibility the game is an incremental, so having several of these means they probably are. These factors apply to most of the canon incremental games.

"Pure UI" Display. Incrementals typically have a data-driven interface of the game state - there isn't a visual representation of the entities within the game. The interface resembles what might be a control panel in another genre, with a focus on numbers, buttons, and readouts rather than animated sprites or scenes. Even when there are visual elements, like item icons or simple enemy images, the player's main interaction is with non-diegetic, UI-focused components rather than immersive game visuals.

Reduced Consequences. Incrementals tend to have reduced repurcussions for misplaying. They very rarely have fail states, where often the largest consequence is simply not progressing - never losing progress.

Optimization Problems. The predominant gameplay of incrementals is typically solving optimization problems, from deciding which purchase to save up for to reasoning and deciding between different mutually exclusive options the game presents.

Resource Management. Incrementals tend to have a lot of resources within the game to keep track of.

Low-Value Factors

These are low-value factors, meaning they aren't as strongly correlated with incremental games. Incremental games may have none of these, and non-incrementals may have several of these - if a game only has low-value factors, they're probably not an incremental.

Fast Numeric Growth. Numbers in incremental games tend to grow faster than in other genres. There are more instances of superlinear growth. The larger the numbers get, the stronger of a signal this factor is.

Automation. As an incremental game progresses, the player often no longer has to deal with earlier mechanics, by having them either happen automatically or otherwise be replaced with an alternative that requires less player interaction.

Goal-Oriented. Incrementals are often heavily reliant on extrinsic motivation to guide the player. Typically this is through some sort of in-game goal to work towards, such as a certain amount of a resource being required to unlock or purchase something new.

Waiting is a Mechanic. In incremental games, the player may come across times where there is no action they can take, and the game will progress automatically instead. The player must wait for some amount of this automatic progress to occur before they can resume interaction with the game.

Are Roguelites Incrementals?

Having made our variation of the Berlin Interpretation for incremental games, we can compare it to the Berlin Interpretation to determine if there's enough overlap that any game that "passes" the Berlin Interpretation would also pass the incremental variant. That is to say, whether any roguelite would also be considered an incremental game.

The meta-progression of an incremental game could arguably be considered a paradigm shift, and certainly adds some resource management. Goal-oriented would probably also apply. I think anything other than those would be a stretch, and in my opinion that just isn't enough to qualify. To be totally honest, I was never expecting to conclude otherwise though 😉

Sub-Genres

There are some trends in incremental games that go beyond just being a commonly used mechanic, such that they deeply affect the rest of the game design. To a degree each of the games in the canon could arguably be part of distinct sub-genres, but I think these 4 deserve specific mentions:

Loops games are a sub-genre defined by having a core mechanic related to a loop, where the player is deciding the actions taken per loop. Notable examples include Idle Loops, Stuck in Time, Cavernous II, and Increlution. You may also argue Groundhog Life and Progress Knight fall into this sub-genre.

ITRTG-like games are a sub-genre defined by having a core mechanic based on clearing increasingly difficult battles and often tend to have a lot of different mechanics to become progressively stronger. Notable examples include Idling to Rule the Gods, NGU Idle, and Wizard and Minion Idle.

Polynomial Growth games are a sub-genre defined by having a core mechanic related to a higher degree polynomial. Notable examples include the base layer of Antimatter Dimensions and Swarm Simulator.

Upgrades Games is a category popular on flash games websites that featured games focused on buying upgrades that would allow you to attain more currency in some sort of minigame that would earn you more money to buy more upgrades, which I'd argue now belong under the fold of incremental games. Notable examples include the Learn to Fly series and Upgrade Complete.

Cultivation RPGs are a genre of games, books, and anime popular in China that center around being in a fantasy world with characters getting stronger over time. While few of them get translated into English, a fan of incremental games may find the available games interesting.

- +.


Referenced by:Incremental SocialKronos

Video games are placed into genres for a variety of reasons. They can give a mental shorthand to set the player's expectations up, they can help a game market itself by its similarities to other, already popular games, and honestly, people just love categorization for its own sake. For this guide, it's important to define the genre so it is clear what games it's even talking about.

This poses a problem. Genres, being Social Constructs, suffer from the usual issues social constructs have of being vague and shifting over time. "Incremental", in particular, is a horribly vague way to define games. Most games have numbers going up in some form or another. We need a more specific definition - similar to how "strategy" can't just mean any game with any amount of strategy because that would be most games. What specifically differentiates incremental games from the rest?

"Incremental" implies it's a genre defined by a game mechanic, but all those game mechanics it could imply exist in many other games. Having a skill tree or upgrades doesn't make you incremental, and if a reset mechanic is all it takes then every roguelite would be an incremental as well. So clearly there's more to it than that - what makes an incremental an incremental?

I'd like to go over a couple of popular suggestions I've seen on defining the genre here. I have my personal preferences and will state them here, but I don't think there's a truly perfect answer.

BTW, if this article made you realize discourse around defining genres is actually a really interesting, even fascinating, topic, I recommend this video essay: Who Shot Guybrush Threepwood? | Genre and the Adventure Game.

Disclaimer: I mostly play incremental games on my computer, and my definitions will be heavily biased towards the games I'm familiar with.

Incrementals vs Idlers vs Clickers

Oftentimes people refer to this genre as idle games and/or clicker games. You'll even find a trend of oxymoronic game titles that contain both terms. "Incremental games" is the umbrella term both those terms fall under. However, I'd like to argue that not only is it better to just use the term "incremental games", but calling them "idle games" or "clicker games" is wrong. Almost universally, these terms are used interchangeably to refer to the same kind of game, where you start the game click spamming and eventually automate the process. Frankly, that kind of game deserves neither title, and the genre of incremental games has trended away from ever requiring click spamming, as it's a bad mechanic, anyways.

While these games do span a spectrum of how active it requires you to be, and sorting games by that metric can be useful for those looking for a particular experience, the borders of when an incremental game counts as an "idler" is too blurry for the term to be useful. "Incremental games" may not be a great descriptive term for the genre (hence this many thousands of words long page on defining what the genre even is), but it's strictly better than calling them "idler" or "clicker" games. This guide will always use the term "incremental games" unless quoting someone else, as it is the term you typically see on all modern games in the genre.

Incrementals as Parodies

Let's start with one of the most interesting definitions of incremental games. Incremental games appear to be distilled versions of games or genres, "revealing" the naked game design at the core of these games or genres not unlike how parodies comment upon their source material.

To understand what that means, think of how a casino uses skinner boxes to emotionally manipulate its customers to keep playing, but "dressing" up the skinner box with tons of stimuli to hide that ultimately the goal is to condition you into coming back compulsively. The idea that incremental games are parodies means taking the stance that at some level all games are similarly manipulating you, giving dopamine rewards in a way that manipulates you to keep playing while not necessarily giving you any value or fulfillment. Incremental games, then, are any games that plainly display the skinner box, and the manipulative core of the game, at the forefront of the experience.

While incremental games can be fun and even healthy in certain contexts, they can exacerbate video game addiction more than other genres. If you feel like playing incremental games is taking priority over other things in your life, or manipulating your sleep schedule, it may be prudent to seek help. See r/StopGaming for resources.

This "undressing" tends to go hand in hand with a reduced focus on aesthetics, often just printing the game state directly to the screen as text. This makes incremental games much easier to develop, particularly for those with programming skills but not art skills, but that's a tangent for why Incremental Games Guide to Incrementals/Appeal to Developers.

Before I continue, I'd like to make my stance clear that I love games and incremental games, and do not think they should be considered inherently bad or manipulative with the above logic. Skinner boxes are just a way of manipulating behavior via rewards. The games are still fun - that's the reward! I'd believe the real criticism here is that it is "empty fun", or "empty dopamine", that doesn't offer any additional value or sense of fulfillment. I don't think that's inherently bad in moderation, although it can become a problem if the game is manipulating you for profit-seeking, or if you play the game to the detriment of the other parts of your life.

Another interpretation of incremental games as parodies comes from several mainstream incremental games that are also parodies of capitalism, such as cookie clicker and adventure capitalist. It's a very common framework for incremental games to portray the ever-increasing numbers as an insatiable hunger for resources, like the ones observed within capitalism. Therefore, these games are used as evidence that the genre as a whole is about parody and commentary.

Popular videos on incremental games that portray the genre as parodies are Why Idle games make good satire, and how it was ruined. and Bad Game Design - Clicker Games. You may also be interested in this response to the latter video from a fan of incremental games: BadGood Game Design - Clicker Games.

I think that this definition ultimately ascribes a motive to the genre as a whole that only happens to apply to some of the more mainstream titles. There certainly are incremental games commenting on different things, including the genre itself as in the case of The Prestige Tree Classic, The Ascension Tree, or Omega Layers, but certainly not all. And of course, not all games that comment on something or parody something are incremental games! Additionally, a very large majority of incremental games are mobile games using these manipulative strategies to get players to spend as much money as possible - hell, Adventure Capitalist is ostensibly a critique on capitalism but features microtransactions and gameplay that manipulates you into buying them! These profit-seeking incremental games certainly belong within the genre but are hardly parodies when they too use manipulation to serve their interests. Also, from my own anecdotal experience, those who use this definition seem to do so from a fairly surface-level familiarity with the genre, and often in the context of criticizing the genre or the fans thereof.

Incrementals as NGU

Another broad definition often used is that incremental games are games where the focus of the game is "numbers going up". This definition proposes that other genres simply use increasing numbers as a means to an end, but incremental games uniquely only care about the numbers themselves going up. Put another way, it implies there should be no narrative justification for the numbers going up other than "why shouldn't they be going up?"

While this definition is common because it feels easy to understand, it is difficult to formally define. Often phrases are used to describe games using this framework, such as having an "exaggerated sense of progression" or "big" numbers. These terms are vague and don't demonstrate an actual threshold between non-incrementals and incrementals. Most games have a sense of progression, so when is it "exaggerated"? How big are "big" numbers? Most notably, RPGs that are typically not considered incrementals will often pass this definition.

Additionally, a lot of incrementals tend to have some theme guiding the gameplay, or at least the names of mechanics. This makes the line blurred between when numbers are going up for their own sake versus for a contextual reason. I believe this point is best illustrated that, while most RPGs are not considered incremental games, there is a sub-genre of "incremental RPGs" that typically relates to RPGs that perform combat automatically. This definition of incremental games does not support RPGs and "incremental RPGs" being on distinct sides of the line if the only difference between them is manual vs automatic combat.

Incrementals as Strategies

This is a rarer interpretation, but there are similarities between incremental games and strategy games, implying incrementals might just be a sub-genre of strategy games. By this approach, incremental games would be defined by their relation to strategy games, and how they involve player strategy. Incremental games are often large optimization problems - above all else, the actual gameplay the player is performing is deciding what to do next. The consequences of wrong decisions are typically more lenient in incremental games - such as just not making optimal progress - but they certainly get complex.

So if we accept the premise that incrementals could fall under strategy, we still need to define what makes a strategy game an incremental versus some other strategy sub-genre. This is a bit tricky due to one particular sub-genre of strategy games: Factory Builders.

Factory builders, such as Factorio or Satisfactory, are games about gaining ever increasing resources, optimizing production, and expanding more and more. That... sounds pretty similar, doesn't it? In fact, there's been some debate on whether factory builders would fall under the "incremental" umbrella. I think it's safe to say the two are certainly related, and probably have quite a bit of overlap in playerbase.

Roguelites as Incrementals?

Earlier on, I mentioned reset mechanics shouldn't be used in the definition because that could make all roguelites incrementals... But what if it does? A lot of incrementals can be described as games with a strong sense of progression, often with layers of meta-progression. Roguelites fit that bill to a T. What would make roguelites not incremental? I honestly don't think there's a good explanation here, but many fans of incremental games will state they do believe the two genres to be unrelated, even if there's a significant overlap between their player bases due to having similar appealing traits.

At this point, it'd be appropriate to consider what part of the definition of roguelites precludes them from also being incrementals, but that reveals a new problem: What are roguelites? They're usually defined as rogue_likes with meta-progression, but that just pushes the problem back a step: Incrementals aren't the only genre to have difficulties defining themselves, it seems! Roguelikes are another genre where the community argues over the formal definition of their genre, although that means we can borrow from their process of coming to a consensus, and maybe come across a viable definition for incremental games.

The Berlin Interpretation

By far the most popular way of defining roguelikes is the "Berlin Interpretation", which acknowledged the diversity of games within the genre and argued the definition should not be based on any ideals about what the genre ought to be, but rather defined by "its canon". They argued there are a handful of games that can be used to define the canon for roguelikes, and from those games, a list of factors can be derived to determine a game's "roguelikeness". The more factors a game has, the more of a roguelike it is. This strategy is very lenient, allowing a game to not present any specific factor so long as it shows enough, and accounts for the blurriness of any genre definition by not explicitly stating how many factors a game must have to qualify as a definite roguelike.

I believe this strategy for defining genres can be applied to other genres as well. A handful of games can be argued to be the incremental games canon, and a list of factors derived from them can be used to judge any game based on its "incrementalness". I'll propose such a canon and list of factors here, but by no means should it be considered the end-all-be-all.

Note: The "Temple of the roguelike", an authority within the genre, has since replaced the Berlin Interpretation with a new set of factors here: https://blog.roguetemple.com/what-is-a-traditional-roguelike/

A Modern Incremental Games Canon

Alright, time to get controversial. Up til now, I've been trying my best to stay objective and analytical, but now it's time to start making some opinionated decisions. I've created a list of games I think could be justified in making up a modern incremental games canon.

Before I mention the list, let's establish how I got to this list. First off, I'm really focusing on building a definition of the genre today, so I prefer modern games over traditional ones. A canon of culturally or historically significant titles to the genre would give a different list. Keep in mind the original Berlin interpretation (and the temple's update to it) were trying to define "traditional roguelikes", which is not my objective here. Building a canon that aims to trace the history of the genre is still valid and useful.

I'm also trying to ensure I pick a large breadth of incremental games, so I'm going to approach the list as a list of archetypes, with a single game to represent it but with other titles mentioned as other examples. This approach places each archetype as equally important, even if one only has a couple entries. Besides the impracticality of a canon that just includes every game, it'd be very biased towards games with large modding communities like Cookie Clicker or The Prestige Tree.

With all that behind us, here is a list of games I think could justifiably make up a Modern Incremental Games Canon:

  • Dodecadragons

    This game represents incremental games with many prestige layers that often have rapid resets and automate lower layers as more get unlocked. Other examples could also include The Prestige Tree, Really Grass Cutting Incremental Classic, Distance Incremental, or the massive modding community TPT has. A lot of the games I've personally worked on fall in this group, like Advent Incremental.

  • Evolve Idle

    This game represents incremental games with few prestige layers, very slow resets, and a focus on resource management. Typically involve some sort of worker allocation. Other examples would be Kitten's Game, Shark Game, or Magic Research.

  • (the) Gnorp Apologue

    This game represents incremental games with a central mechanic that gets added to by various other mechanics. All the mechanics remain relevant throughout the game, with different ones contributing most over time. Other examples include Nodebuster and To the Core. A lot of traditional games also fall in this archetype by having characters or buildings you level up, that each contribute additively to gaining the primary resources. These include Cookie Clicker, Clicker Heroes, and Realm Grinder. In a way, that makes the modern titles mentioned in this archetype the spiritual successors of those traditional games, and exemplifies how the genre has changed.

  • Idle Momentum

    This game represents incremental games that include polynomial growth as a central mechanic that is then built upon. Other examples include Antimatter Dimensions, Swarm Simulator, and Derivative Clicker.

  • Melvor Idle

    This game represents incremental games that are essentially a genre blend between incremental games and RPGs. Compared to other types of RPGs, these games have a focus on progressing while idle. Other examples would be IdleOn and a very large amount of mobile RPGs.

  • Stuck in Time

    This game represents incremental games that include a reset mechanic where there are pre-defined decisions being made during the course of the run. There's typically a concept of a playable character, whose actions are being "queued up" during a run, and these runs become longer or otherwise more productive as the game progresses. There are a lot of examples of this genre, including Cavernous II, Increlution, Progress Knight, Idle Loops, and Groundhog Life.

  • Universal Paperclips

    This game represents incremental games that involve several phases of completely distinct gameplay that fully replace the previous, called "paradigm shifts". Prestige layers are also often paradigm shifts, but this game represents paradigm shifts that are not reset mechanics but still transform the gameplay. Other examples would be Crank or A Dark Room. Spore would be an example that's not typically considered an incremental.

  • Unnamed Space Idle

    This game represents incremental games that focus on unlocking many different independent progression systems that boost each other, and all remain relevant throughout the course of the game. Other examples include NGU Idle, Anti-Idle, Idle Skilling, and Idle Wizard.

It may look like I've just shifted the problem down a level - rather than defining the genre, I'm now defining a bunch of sub-genres. However, the methods used here for defining the canon, and my attempt at ensuring a breadth of games by determining distinct archetypes, is just my approach. This list is additionally biased towards games I'm more familiar with, which will differ person to person. The only hard and fast rule is that every game on the list should be nearly universally accepted as an incremental game. So long as you do that, the factors should be relatively similar, although ofc individuals will still likely have small differences, as is the nature of socially constructed definitions.

Naturally this canon is a perpetual work-in-progress. I'm currently a bit uncertain about the distinctions between the evolve idle, melvor idle, and unnamed space idle archetypes. I could see those being rewritten as two or even a single archetype.

Unfolding

There are several related concepts mentioned in the canon - unfolding, prestige layers, and paradigm shifts. Unfolding is the umbrella term which includes the other two, and is clearly the highest possible value factor for an incremental. It's so common that for a while people referred to incrementals that exhibit this trait as "unfolding" games, to the point of trying to replace the term incremental due to their popularity.

There are many reasons for the appeal of unfolding mechanics. Oftentimes each mechanic builds on top of the existing mechanics, increasing the complexity of the game in steps so the player can follow along. In fact, sometimes the older mechanics will be entirely phased out (e.g. by automating them), so the complexity of the game remains roughly equal throughout the game. In any case, adding new mechanics regularly provides a sense of mystery, with the player anticipating what will happen next. They shake up the gameplay before it gets too stale - allowing the game to entertain for longer before the sense of Guide to Incrementals/What is Content? dissipates. Of the canon games selected above, I would argue every single one contains unfolding to some degree.

I should take a moment to say that while I'm hyping up this specific factor, we cannot just reduce the genre definition to "does it introduce new mechanics over time". Many games have paradigm shifts that are not incremental, so it's just an indicator of incrementalness. Every single canon game may show that it's common amongst incremental games, but could just as easily indicate that they're common in games in general.

High-Value Factors

I won't take as long to discuss the high and low-value factors, as you've already seen most of them brought up earlier on this page. As a reminder, a game does NOT need all of these to be an incremental game, but these are factors that each indicate a strong possibility the game is an incremental, so having several of these means they probably are. These factors apply to most of the canon incremental games.

"Pure UI" Display. Incrementals typically have a data-driven interface of the game state - there isn't a visual representation of the entities within the game. The interface resembles what might be a control panel in another genre, with a focus on numbers, buttons, and readouts rather than animated sprites or scenes. Even when there are visual elements, like item icons or simple enemy images, the player's main interaction is with non-diegetic, UI-focused components rather than immersive game visuals.

Reduced Consequences. Incrementals tend to have reduced repurcussions for misplaying. They very rarely have fail states, where often the largest consequence is simply not progressing - never losing progress.

Optimization Problems. The predominant gameplay of incrementals is typically solving optimization problems, from deciding which purchase to save up for to reasoning and deciding between different mutually exclusive options the game presents.

Resource Management. Incrementals tend to have a lot of resources within the game to keep track of.

Low-Value Factors

These are low-value factors, meaning they aren't as strongly correlated with incremental games. Incremental games may have none of these, and non-incrementals may have several of these - if a game only has low-value factors, they're probably not an incremental.

Fast Numeric Growth. Numbers in incremental games tend to grow faster than in other genres. There are more instances of superlinear growth. The larger the numbers get, the stronger of a signal this factor is.

Automation. As an incremental game progresses, the player often no longer has to deal with earlier mechanics, by having them either happen automatically or otherwise be replaced with an alternative that requires less player interaction.

Goal-Oriented. Incrementals are often heavily reliant on extrinsic motivation to guide the player. Typically this is through some sort of in-game goal to work towards, such as a certain amount of a resource being required to unlock or purchase something new.

Waiting is a Mechanic. In incremental games, the player may come across times where there is no action they can take, and the game will progress automatically instead. The player must wait for some amount of this automatic progress to occur before they can resume interaction with the game.

Are Roguelites Incrementals?

Having made our variation of the Berlin Interpretation for incremental games, we can compare it to the Berlin Interpretation to determine if there's enough overlap that any game that "passes" the Berlin Interpretation would also pass the incremental variant. That is to say, whether any roguelite would also be considered an incremental game.

The meta-progression of an incremental game could arguably be considered a paradigm shift, and certainly adds some resource management. Goal-oriented would probably also apply. I think anything other than those would be a stretch, and in my opinion that just isn't enough to qualify. To be totally honest, I was never expecting to conclude otherwise though 😉

Sub-Genres

There are some trends in incremental games that go beyond just being a commonly used mechanic, such that they deeply affect the rest of the game design. To a degree each of the games in the canon could arguably be part of distinct sub-genres, but I think these 4 deserve specific mentions:

Loops games are a sub-genre defined by having a core mechanic related to a loop, where the player is deciding the actions taken per loop. Notable examples include Idle Loops, Stuck in Time, Cavernous II, and Increlution. You may also argue Groundhog Life and Progress Knight fall into this sub-genre.

ITRTG-like games are a sub-genre defined by having a core mechanic based on clearing increasingly difficult battles and often tend to have a lot of different mechanics to become progressively stronger. Notable examples include Idling to Rule the Gods, NGU Idle, and Wizard and Minion Idle.

Polynomial Growth games are a sub-genre defined by having a core mechanic related to a higher degree polynomial. Notable examples include the base layer of Antimatter Dimensions and Swarm Simulator.

Upgrades Games is a category popular on flash games websites that featured games focused on buying upgrades that would allow you to attain more currency in some sort of minigame that would earn you more money to buy more upgrades, which I'd argue now belong under the fold of incremental games. Notable examples include the Learn to Fly series and Upgrade Complete.

Cultivation RPGs are a genre of games, books, and anime popular in China that center around being in a fantasy world with characters getting stronger over time. While few of them get translated into English, a fan of incremental games may find the available games interesting.

+ \ No newline at end of file diff --git a/hashmap.json b/hashmap.json index 50157cbc1..214f523c8 100644 --- a/hashmap.json +++ b/hashmap.json @@ -1 +1 @@ -{"about_index.md":"YpmaDm_z","garden_chronological_index.md":"D5fWpnlX","garden_babble-buds_index.md":"DxmqVoTA","garden_cinny_index.md":"CWxQ-zXy","garden_atproto_index.md":"D9_7sfO7","garden_chromatic-lattice_index.md":"Cw8Kko32","garden_advent-incremental_index.md":"CMk1AiJQ","garden_art-is-never-complete_index.md":"BPd82nXo","garden_consensus-democracy_index.md":"DiXMmLIQ","garden_artificial-intelligence_index.md":"CBlCYWkr","garden_a-plea-to-organize_index.md":"CyK1zn1I","changelog_index.md":"DVgSDeNX","garden_davey-wreden_index.md":"f3xZ_s4l","garden_everything-is-political_index.md":"CdBgMXxj","guide-to-incrementals_ludology_appeal-gamers_index.md":"DEXlbts1","garden_enshittification_index.md":"B1b1fu7S","garden_commune_index.md":"COmv47Qq","garden_local-first-software_index.md":"D2a4gu-W","garden_the-cozy-web_index.md":"D01M1HnW","garden_vitepress_index.md":"tx4a0n5q","garden_freeform-vs-chronological-dichotomy_index.md":"DYWAb1HB","garden_garden-rss_index.md":"AWGxD-E4","garden_gender-performativity_index.md":"CnW1xA_a","garden_individualism_index.md":"ynjLdsuX","garden_fedi-v2_index.md":"Dk37-aPG","garden_guide-to-incrementals_index.md":"5BLfRn5b","garden_gender_index.md":"DZdlSD4a","guide-to-incrementals_index.md":"DPTKaCuc","garden_guide-to-incrementals_appeal-to-developers_index.md":"CkuW5uER","garden_decentralized-identity_index.md":"y4RFh3rh","garden_local-communities_index.md":"D3DH0fGC","garden_gerrymandering_index.md":"CX2OFSlv","garden_open-source_index.md":"6oyBcdDm","garden_guide-to-incrementals_navigating-criticism_index.md":"uvCjn02L","garden_debate_index.md":"DcD9KhbD","garden_anarchism_index.md":"Bi4VyWbV","garden_police-abolition_index.md":"CU68gI68","garden_my-browser-stack_index.md":"DCchRRYs","garden_personality_index.md":"ChhNeN5J","garden_planar-pioneers_index.md":"7VDRFjaj","guide-to-incrementals_ludology_appeal-developers_index.md":"D48oheRE","garden_orchard_index.md":"BJ1pQXIs","garden_digital-gardens_index.md":"ChR2AWpj","garden_dice-armor_index.md":"ByqRXWDk","garden_the-small-web_index.md":"Bkk1rEfe","garden_opti-speech_index.md":"Dp0ll6kT","garden_life-is-strange_index.md":"CQykqggC","garden_leftism_index.md":"CYOK2kei","garden_freeform_index.md":"DrTiVQ1a","garden_forgejo_index.md":"GiARxfDT","garden_guide-to-incrementals_what-is-content_index.md":"BEKNdnys","garden_direct-democracy_index.md":"DYir6dY7","garden_kronos_index.md":"BX3T3aQP","garden_representative-democracy_index.md":"DuqwAFuu","garden_command-palettes_index.md":"CTOBvuQi","garden_premium-currency_index.md":"ChZ8mdPg","garden_capture-the-citadel_index.md":"-br6Pcc8","garden_chat-glue_index.md":"BFBOFQOt","garden_decentralized_index.md":"B4L35X0Y","garden_mbin_index.md":"Bpoe92vo","garden_matrix_index.md":"Cat_AW6q","garden_scientific-constructivism_index.md":"R4zVkePt","garden_synapse_index.md":"BJZE3okQ","garden_the-beginner-s-guide_index.md":"k50dHl69","garden_my-projects_index.md":"DQ9IsS7b","garden_neoliberalism_index.md":"D3ylIaui","garden_digital-locality_index.md":"zReLaiCJ","garden_nostr_index.md":"DpzGkNqA","garden_decentralized-moderation_index.md":"Vc-f-eOL","garden_v-ecs_index.md":"BkjNGrNG","garden_virality_index.md":"Bw3Icu9N","garden_ivy-road_index.md":"CnA7kCGP","garden_pre-order-bonuses_index.md":"BuOtoWs6","garden_the-indieweb_signature-blocks_index.md":"BdHKJnLs","garden_the-indieweb_amplification_index.md":"l9pwOcN0","garden_incremental-social_index.md":"Dr5ZrztL","garden_social-media_index.md":"BaJiZhWB","garden_profectus_index.md":"CvajevSf","garden_mtx_index.md":"BbdJq7Ny","public_kronos_readme.md":"gWCvo8NR","guide-to-incrementals_ludology_definition_index.md":"Cv0KfjdU","garden_video-game-monetization_index.md":"DDBSiidE","garden_this-knowledge-hub_index.md":"CLJqAHFR","garden_weird_index.md":"BSTJrWy3","garden_my-political-journey_index.md":"D7DllfwU","garden_webrings_index.md":"CxDR81HA","garden_political-quizzes_index.md":"R467aSgs","garden_video-essays_index.md":"Dnw2MNSD","garden_filter-bubbles_index.md":"-FC6NYD-","garden_network-of-knowledge_index.md":"CRNiO9eP","garden_game-dev-tree_index.md":"YpLH-Pt3","garden_my-personal-website_index.md":"DLhI2FKw","garden_decentralized-social-media_index.md":"D0uxpYG3","garden_social-constructs_index.md":"D9tB0zu2","garden_objectivity_index.md":"COU01MD8","garden_moderation_index.md":"BM0rdbL6","index.md":"C1CHMYCi","public_gamedevtree_readme.md":"DE0tbltW","garden_prescriptivism-vs-descriptivism_index.md":"Z9HaEgJU","public_gamedevtree_changelog.md":"33CNNJKT","garden_my-political-beliefs_index.md":"BOiL5pI1","public_gamedevtree_docs_!general-info.md":"DE0Ke1e2","public_gamedevtree_docs_achievements.md":"C0yB95Wu","public_gamedevtree_2.0-format-changes.md":"Bczdru-g","now_index.md":"ReRq890H","public_kronos_docs_achievements.md":"KsbXJC1r","public_kronos_changelog.md":"D-HmMLD4","public_kronos_docs_bars.md":"CSguFZp_","public_kronos_docs_basic-layer-breakdown.md":"B8H1fhgA","guide-to-incrementals_design_criticism_index.md":"BcTt1ntM","public_kronos_docs_buyables.md":"Bnk8zkua","guide-to-incrementals_ludology_content_index.md":"BMb_w6x8","public_kronos_docs_!general-info.md":"DBOKRLme","public_kronos_docs_clickables.md":"BjE13u2w","public_kronos_docs_grids.md":"D6W3aZvd","public_kronos_docs_getting-started.md":"mxo4iirj","public_kronos_docs_layer-features.md":"B0ijhoip","garden_imperialism_index.md":"D1389wsm","public_kronos_docs_custom-tab-layouts.md":"livval5T","public_kronos_docs_trees-and-tree-customization.md":"CIBisQ1N","garden_logseq_index.md":"DO7LVfYN","public_kronos_docs_upgrades.md":"Di0rXgVe","public_lit_docs_getting-started.md":"CK27tjNE","public_lit_docs_custom-tab-layouts.md":"BoQJFtTn","public_lit_docs_trees-and-tree-customization.md":"C9RmdUn6","public_lit_docs_subtabs-and-microtabs.md":"_yQ1-Rr1","public_lit_docs_milestones.md":"DW0yfQPK","public_lit_docs_updating-tmt.md":"KobKYOhn","public_lit_docs_upgrades.md":"B0k22Nxf","public_lit_docs_infoboxes.md":"CuZo0M8o","public_lit_docs_basic-layer-breakdown.md":"CsZKnxwf","public_lit_docs_buyables.md":"78Vp9b6u","public_lit_docs_challenges.md":"Z9Rj0YIU","public_lit_readme.md":"CsmWLhmX","public_lit_docs_layer-features.md":"4M5Xu4L1","garden_wanderstop_index.md":"Br2zW1VJ","garden_no-politics-rules_index.md":"CX084uTP","garden_fediverse_index.md":"mR-c57ag","garden_guide-to-incrementals_defining-the-genre_index.md":"CbFSfPEj","garden_technocracy_index.md":"CtShObzY","garden_trans-athletes-in-sports_index.md":"DNc7lBCE","public_kronos_docs_main-mod-info.md":"P75-j5rD","public_gamedevtree_docs_subtabs-and-microtabs.md":"CMFhzxtB","public_gamedevtree_docs_upgrades.md":"PvuguZyE","public_kronos_docs_particles.md":"DUOsroj0","public_lit_docs_clickables.md":"BH0xyi8n","public_gamedevtree_docs_challenges.md":"CE_eHHwf","public_gamedevtree_docs_basic-layer-breakdown.md":"Yqwj_xfc","public_gamedevtree_docs_buyables.md":"B23LDgI6","public_gamedevtree_docs_bars.md":"CUbXgosN","public_gamedevtree_docs_milestones.md":"CWaYObZs","public_gamedevtree_docs_getting-started.md":"hNeDDqaD","public_lit_old things_2.0-format-changes.md":"BZuK-caS","public_kronos_docs_challenges.md":"Cs3Vfgw-","public_kronos_docs_updating-tmt.md":"M9T22mdH","garden_guide-to-incrementals_appeal-to-players_index.md":"CA3L_dhG","public_lit_docs_!general-info.md":"DJIpd8t5","public_gamedevtree_docs_infoboxes.md":"bLloeIuf","public_lit_docs_achievements.md":"DxD0wCNF","public_kronos_docs_milestones.md":"C15QtFf1","public_gamedevtree_docs_updating-tmt.md":"BX_YXvdE","public_kronos_docs_subtabs-and-microtabs.md":"CE1p7Oy-","public_lit_docs_main-mod-info.md":"BMD6V4Fr","public_gamedevtree_docs_main-mod-info.md":"BCNaY-_6","public_kronos_old things_2.0-format-changes.md":"QUX27CIC","public_kronos_docs_infoboxes.md":"DoJEZ-co","public_gamedevtree_docs_custom-tab-layouts.md":"DNTfGub2","public_gamedevtree_docs_layer-features.md":"Crq83lMF","public_lit_docs_bars.md":"DclDejG3","public_lit_changelog.md":"CthDV5ot","public_gamedevtree_docs_clickables.md":"Ck1H6VJz"} +{"garden_webrings_index.md":"C9YRZ8vb","guide-to-incrementals_index.md":"Bpq15UaX","garden_chromatic-lattice_index.md":"B5qPBo-S","garden_weird_index.md":"BjZi1MDu","garden_the-indieweb_signature-blocks_index.md":"C4-BOO4I","garden_babble-buds_index.md":"CRllazQ1","garden_this-knowledge-hub_index.md":"BAlSWWx9","garden_synapse_index.md":"j2MWsuO_","garden_atproto_index.md":"ITAYOGJR","garden_fediverse_index.md":"DdsbJhRP","garden_cinny_index.md":"CKXJ1bbs","garden_technocracy_index.md":"CX0DwK9Y","garden_the-beginner-s-guide_index.md":"B9s_UlL-","garden_the-cozy-web_index.md":"DaheNEdp","garden_imperialism_index.md":"CshuexhP","garden_art-is-never-complete_index.md":"BtIYQjow","garden_command-palettes_index.md":"DPkTiZSA","garden_filter-bubbles_index.md":"qLDBKf98","garden_the-indieweb_amplification_index.md":"3x5VqZ80","about_index.md":"YpmaDm_z","guide-to-incrementals_design_criticism_index.md":"CF3ptiyg","guide-to-incrementals_ludology_appeal-gamers_index.md":"Cmpvya3x","guide-to-incrementals_ludology_appeal-developers_index.md":"CimyBWKE","garden_anarchism_index.md":"CER_o3nm","garden_artificial-intelligence_index.md":"VFi9pcqA","garden_decentralized_index.md":"bryhD8xj","garden_a-plea-to-organize_index.md":"DmEe_rYO","garden_chat-glue_index.md":"BUFDcaM4","garden_everything-is-political_index.md":"rbSDwqZc","garden_guide-to-incrementals_what-is-content_index.md":"DZ5pJU-H","garden_consensus-democracy_index.md":"CofuRdBH","garden_decentralized-identity_index.md":"BEIMlpi0","garden_decentralized-moderation_index.md":"ueaXQznW","garden_guide-to-incrementals_navigating-criticism_index.md":"DivZ76BD","garden_davey-wreden_index.md":"gXQRuuUm","changelog_index.md":"ilnyzBD3","garden_moderation_index.md":"B7RP_VZ_","garden_garden-rss_index.md":"BuAHk1MQ","garden_gender_index.md":"DoQhDjKl","garden_mtx_index.md":"BsaqlBYK","public_gamedevtree_docs_custom-tab-layouts.md":"DNTfGub2","garden_my-browser-stack_index.md":"uksLZ895","garden_direct-democracy_index.md":"Drd3bOt8","public_gamedevtree_docs_challenges.md":"CE_eHHwf","public_kronos_docs_layer-features.md":"B0ijhoip","garden_leftism_index.md":"DU61D021","public_kronos_docs_infoboxes.md":"DoJEZ-co","garden_life-is-strange_index.md":"CiHEZNoV","public_kronos_docs_grids.md":"D6W3aZvd","garden_logseq_index.md":"BjYPX9U_","garden_matrix_index.md":"B2azu3Wc","garden_local-first-software_index.md":"Cb7v9klo","garden_dice-armor_index.md":"BvcL1Xmx","garden_mbin_index.md":"DqnlhoRc","garden_fedi-v2_index.md":"CThQv-zy","garden_local-communities_index.md":"CAEN6S2r","garden_my-political-beliefs_index.md":"BYXcV_fb","garden_my-political-journey_index.md":"BXr8MFu7","garden_my-projects_index.md":"wiE69CCE","garden_my-personal-website_index.md":"D9RxR9Ge","garden_neoliberalism_index.md":"ui08wbfa","garden_gerrymandering_index.md":"CsB_YWSB","garden_objectivity_index.md":"DVnccZzk","garden_network-of-knowledge_index.md":"CyD-TRX8","garden_nostr_index.md":"CEXJKYHs","garden_freeform-vs-chronological-dichotomy_index.md":"Bc4Lj93E","garden_forgejo_index.md":"4kXC1s_Z","garden_digital-gardens_index.md":"CBAUQVhO","garden_digital-locality_index.md":"CqP1_XyW","garden_enshittification_index.md":"DPNqV21w","garden_game-dev-tree_index.md":"BYDVgNyE","garden_no-politics-rules_index.md":"C_dydAdq","public_gamedevtree_docs_subtabs-and-microtabs.md":"CMFhzxtB","public_kronos_docs_getting-started.md":"mxo4iirj","public_kronos_docs_bars.md":"CSguFZp_","public_gamedevtree_changelog.md":"33CNNJKT","public_gamedevtree_docs_buyables.md":"B23LDgI6","public_kronos_docs_achievements.md":"KsbXJC1r","public_gamedevtree_readme.md":"DE0tbltW","garden_planar-pioneers_index.md":"k-RkmoSH","public_kronos_docs_clickables.md":"BjE13u2w","public_kronos_readme.md":"gWCvo8NR","public_lit_docs_main-mod-info.md":"BMD6V4Fr","public_lit_docs_subtabs-and-microtabs.md":"_yQ1-Rr1","public_lit_docs_milestones.md":"DW0yfQPK","public_lit_docs_updating-tmt.md":"KobKYOhn","public_lit_docs_upgrades.md":"B0k22Nxf","public_gamedevtree_docs_upgrades.md":"PvuguZyE","public_lit_docs_layer-features.md":"4M5Xu4L1","public_lit_docs_buyables.md":"78Vp9b6u","public_lit_docs_challenges.md":"Z9Rj0YIU","public_lit_docs_clickables.md":"BH0xyi8n","public_lit_docs_custom-tab-layouts.md":"BoQJFtTn","public_lit_docs_getting-started.md":"CK27tjNE","public_lit_docs_infoboxes.md":"CuZo0M8o","garden_decentralized-social-media_index.md":"B0rgV0sO","guide-to-incrementals_ludology_content_index.md":"zhZ55mqj","garden_guide-to-incrementals_appeal-to-developers_index.md":"DlM-Yrns","public_lit_old things_2.0-format-changes.md":"BZuK-caS","public_lit_readme.md":"CsmWLhmX","public_lit_docs_achievements.md":"DxD0wCNF","public_lit_docs_!general-info.md":"DJIpd8t5","public_lit_docs_bars.md":"DclDejG3","garden_orchard_index.md":"D91PKd0A","public_gamedevtree_docs_main-mod-info.md":"BCNaY-_6","public_lit_docs_basic-layer-breakdown.md":"CsZKnxwf","public_gamedevtree_docs_bars.md":"CUbXgosN","public_gamedevtree_docs_achievements.md":"C0yB95Wu","garden_guide-to-incrementals_index.md":"CaQpBwBw","public_gamedevtree_docs_basic-layer-breakdown.md":"Yqwj_xfc","public_gamedevtree_2.0-format-changes.md":"Bczdru-g","public_lit_docs_trees-and-tree-customization.md":"C9RmdUn6","garden_pre-order-bonuses_index.md":"C3KYEqnW","garden_open-source_index.md":"Cacbphit","garden_personality_index.md":"ClTZlrBX","garden_social-media_index.md":"Dq5kAlQ5","garden_commune_index.md":"CoCiInjd","garden_virality_index.md":"DfY8NXAh","garden_trans-athletes-in-sports_index.md":"Ckznm2z3","public_lit_changelog.md":"CthDV5ot","garden_opti-speech_index.md":"f2BVQmXm","garden_guide-to-incrementals_defining-the-genre_index.md":"CRfSx2qs","garden_political-quizzes_index.md":"C0oamyiX","public_kronos_docs_custom-tab-layouts.md":"livval5T","public_kronos_docs_buyables.md":"Bnk8zkua","garden_social-constructs_index.md":"B2XU4IXD","garden_vitepress_index.md":"DO0hrupk","garden_chronological_index.md":"Zheg5VVb","garden_video-essays_index.md":"ChIx1pnZ","public_gamedevtree_docs_updating-tmt.md":"BX_YXvdE","garden_wanderstop_index.md":"CHEMH1CM","garden_ivy-road_index.md":"DZ7vqlGJ","public_kronos_old things_2.0-format-changes.md":"QUX27CIC","public_kronos_docs_main-mod-info.md":"P75-j5rD","garden_debate_index.md":"KJcHmWUU","garden_police-abolition_index.md":"CeqMJoCo","garden_kronos_index.md":"dlLMxxFW","public_kronos_docs_upgrades.md":"Di0rXgVe","public_kronos_docs_particles.md":"DUOsroj0","public_kronos_docs_milestones.md":"C15QtFf1","public_kronos_docs_subtabs-and-microtabs.md":"CE1p7Oy-","public_kronos_docs_trees-and-tree-customization.md":"CIBisQ1N","public_kronos_docs_updating-tmt.md":"M9T22mdH","garden_v-ecs_index.md":"47YLBRh-","public_kronos_docs_basic-layer-breakdown.md":"B8H1fhgA","garden_profectus_index.md":"CIxoSPG0","garden_incremental-social_index.md":"BzhAzaXZ","garden_representative-democracy_index.md":"tqYsOBT9","garden_the-small-web_index.md":"BHvDMKRi","garden_premium-currency_index.md":"Bnxgz6Mq","public_gamedevtree_docs_milestones.md":"CWaYObZs","public_gamedevtree_docs_infoboxes.md":"bLloeIuf","garden_prescriptivism-vs-descriptivism_index.md":"D490ZQQV","garden_gender-performativity_index.md":"s4FTNt-A","garden_scientific-constructivism_index.md":"DBE0PQqI","now_index.md":"C9Pm0qfB","index.md":"CNQn2bLH","guide-to-incrementals_ludology_definition_index.md":"CepGvxbT","public_gamedevtree_docs_getting-started.md":"hNeDDqaD","garden_advent-incremental_index.md":"BqEpHWsk","public_gamedevtree_docs_!general-info.md":"DE0Ke1e2","public_kronos_docs_challenges.md":"Cs3Vfgw-","garden_guide-to-incrementals_appeal-to-players_index.md":"OPmcFpqr","public_gamedevtree_docs_clickables.md":"Ck1H6VJz","garden_individualism_index.md":"BpsGeaNn","garden_video-game-monetization_index.md":"DreEsxJJ","public_gamedevtree_docs_layer-features.md":"Crq83lMF","garden_capture-the-citadel_index.md":"CiAmkxr4","garden_freeform_index.md":"CLFdmYH0","public_kronos_changelog.md":"D-HmMLD4","public_kronos_docs_!general-info.md":"DBOKRLme"} diff --git a/index.html b/index.html index 44e222e53..2446a9974 100644 --- a/index.html +++ b/index.html @@ -6,13 +6,13 @@ Hello! | The Paper Pilot - + - + - - + + @@ -50,8 +50,8 @@ -
Skip to content

Hello!

I'm Anthony, or The Paper Pilot, and welcome to my digital garden!

This is a public website collecting all my (public) thoughts and projects all in one place. There are a lot of pages here, that link to each other wiki-style. I suggest starting your browsing with one of the recommended pages that most closely align with your interests 😃.

- +
Skip to content

Hello!

I'm Anthony, or The Paper Pilot, and welcome to my digital garden!

This is a public website collecting all my (public) thoughts and projects all in one place. There are a lot of pages here, that link to each other wiki-style. I suggest starting your browsing with one of the recommended pages that most closely align with your interests 😃.

+ \ No newline at end of file diff --git a/now/index.html b/now/index.html index 78e1af8f3..6a9e38a67 100644 --- a/now/index.html +++ b/now/index.html @@ -6,14 +6,14 @@ /now | The Paper Pilot - + - + - - - + + + @@ -51,10 +51,10 @@ -
Skip to content

/now

186 words, ~1 minute read. Planted +

Skip to content

/now

186 words, ~1 minute read. Planted . Last tended to -.


This "now page" offers a big picture glimpse into what I’m focused on at this point in my life. What is a now page?

Digital Gardens

I'm building (at least) a mockup for Orchard, an app for message gardening into a Network of Knowledge.

Ultimately, I think this project could have some implications on how this digital garden operates, so I've decided to stop further indieweb integrations like webmentions for now. I'd like to see a server be able to bridge indieweb and agentic fediverse posts, and start using the agentic fediverse posts as my new source of truth.

Incremental Social

I'm running and improving the social media site Incremental Social, along with CardboardEmpress.

I'd like to make it host an iroh node for hosting agentic fediverse content, managing a keypair for each account (with options for migration).

Chromatic Lattice

I'm working on a multiplayer incremental game called Chromatic Lattice . It's still largely in the concept phase, and may even be built on the Agentic Fediverse.

Kronos

I'm working on a long single player narratively driven incremental game called Kronos . This is a very long-term project.

- +.


This "now page" offers a big picture glimpse into what I’m focused on at this point in my life. What is a now page?

Digital Gardens

I'm building (at least) a mockup for Orchard, an app for message gardening into a Network of Knowledge.

Ultimately, I think this project could have some implications on how this digital garden operates, so I've decided to stop further indieweb integrations like webmentions for now. I'd like to see a server be able to bridge indieweb and agentic fediverse posts, and start using the agentic fediverse posts as my new source of truth.

Incremental Social

I'm running and improving the social media site Incremental Social, along with CardboardEmpress.

I'd like to make it host an iroh node for hosting agentic fediverse content, managing a keypair for each account (with options for migration).

Chromatic Lattice

I'm working on a multiplayer incremental game called Chromatic Lattice . It's still largely in the concept phase, and may even be built on the Agentic Fediverse.

Kronos

I'm working on a long single player narratively driven incremental game called Kronos . This is a very long-term project.

+ \ No newline at end of file diff --git a/public/gamedevtree/2.0-format-changes.html b/public/gamedevtree/2.0-format-changes.html index 7bd492df2..8a964e64d 100644 --- a/public/gamedevtree/2.0-format-changes.html +++ b/public/gamedevtree/2.0-format-changes.html @@ -6,12 +6,12 @@ 2.0 format changes | The Paper Pilot - + - + - + @@ -50,8 +50,8 @@ -
Skip to content

2.0 format changes

  • Temp format is changed from temp.something[layer] to temp[layer].something, for consistency
  • Challenges are now saved as an object with the amount of completions in each spot. (This will break saves.)
  • effectDisplay in Challenges and Upgrades no longer takes an argument, and neither does effect for Buyables
  • Buyable cost can take an argument for amount of buyables, but it needs to function if no argument is supplied (it should do the cost for the next purchase).
  • Generation of Points now happens in the main game loop (not in a layer update function), enabled by canGenPoints in game.js.
  • Changed fullLayerReset to layerDataReset, which takes an array of names of values to keep

In addition, many names were changed, mostly expanding abbreviations:

All instances of:

  • chall -> challenge
  • unl -> unlocked
  • upg -> upgrade (besides CSS)
  • amt -> amount
  • desc -> description
  • resCeil -> roundUpCost
  • order -> unlockOrder
  • incr_order -> increaseUnlockOrder

Challenges:

  • desc -> challengeDescription
  • reward -> rewardDescription
  • effect -> rewardEffect
  • effectDisplay -> rewardDisplay
  • active -> challengeActive
- +
Skip to content

2.0 format changes

  • Temp format is changed from temp.something[layer] to temp[layer].something, for consistency
  • Challenges are now saved as an object with the amount of completions in each spot. (This will break saves.)
  • effectDisplay in Challenges and Upgrades no longer takes an argument, and neither does effect for Buyables
  • Buyable cost can take an argument for amount of buyables, but it needs to function if no argument is supplied (it should do the cost for the next purchase).
  • Generation of Points now happens in the main game loop (not in a layer update function), enabled by canGenPoints in game.js.
  • Changed fullLayerReset to layerDataReset, which takes an array of names of values to keep

In addition, many names were changed, mostly expanding abbreviations:

All instances of:

  • chall -> challenge
  • unl -> unlocked
  • upg -> upgrade (besides CSS)
  • amt -> amount
  • desc -> description
  • resCeil -> roundUpCost
  • order -> unlockOrder
  • incr_order -> increaseUnlockOrder

Challenges:

  • desc -> challengeDescription
  • reward -> rewardDescription
  • effect -> rewardEffect
  • effectDisplay -> rewardDisplay
  • active -> challengeActive
+ \ No newline at end of file diff --git a/public/gamedevtree/README.html b/public/gamedevtree/README.html index 3d27588e3..daacff605 100644 --- a/public/gamedevtree/README.html +++ b/public/gamedevtree/README.html @@ -6,12 +6,12 @@ The-Modding-Tree | The Paper Pilot - + - + - + @@ -50,8 +50,8 @@ -
Skip to content

The-Modding-Tree

A modified version of The Prestige Tree that is much easier to mod. It still requires programming knowledge, but it's mostly pretty easy things and copy/pasting.

Look here for a tutorial on getting started with modding with TMT

You can look in the documentation for more information on how it all works, or look at the code in layers.js to see what it all looks like.

- +
Skip to content

The-Modding-Tree

A modified version of The Prestige Tree that is much easier to mod. It still requires programming knowledge, but it's mostly pretty easy things and copy/pasting.

Look here for a tutorial on getting started with modding with TMT

You can look in the documentation for more information on how it all works, or look at the code in layers.js to see what it all looks like.

+ \ No newline at end of file diff --git a/public/gamedevtree/changelog.html b/public/gamedevtree/changelog.html index 52fdedcf1..88823b08f 100644 --- a/public/gamedevtree/changelog.html +++ b/public/gamedevtree/changelog.html @@ -6,12 +6,12 @@ The Game Dev Tree changelog: | The Paper Pilot - + - + - + @@ -50,8 +50,8 @@ -
Skip to content

The Game Dev Tree changelog:

v1.0.4 Version Bump [rebalanced,debuggedx3] - 2020-11-09

  • Fixed refactorings 2, 3, and 4 not actually affecting productivity

v1.0.3 Version Bump [rebalanced,debuggedx2] - 2020-11-08

  • Fixed API milestone 4 not working

v1.0.2 Version Bump [rebalanced,debugged] - 2020-11-08

  • Fixed tree lines being hidden after hitting "keepGoing" in the victory screen

v1.0.1 Version Bump [rebalanced] - 2020-11-08

  • Buffed several TAs

v1.0 Version Bump - 2020-11-08

  • Finished row 4
  • Added colored text to lore
  • Fixed some visual bugs with milestones
  • Probably other stuff lol its been a week

v0.2.3 Stylish - 2020-10-30

  • Re-styled basically everything
  • Added favicon
  • Added header bar
  • Added changelog

v0.2.2 Row 3 - 2020-10-22

  • Removed debug statement
  • Moved milestones in F layer beneath the buyables

v0.2.1 Row 3 - 2020-10-21

  • Fixed layers hiding
  • Fixed typos/minor issues
  • Fixed S layer being highlighted before you can unlock the layer

v0.2 Row 3 - 2020-10-21

  • Implemented row 3

v0.1.1 Cash Influx [rebalanced] - 2020-10-19

  • Fixed notification issue
  • Rebalanced to make early game faster and late game slower
  • Fixed other minor issues

v0.1 Cash Influx - 2020-10-19

  • Implemented row 2

v0.0 Initial Commit - 2020-10-18

  • Implemented row 1
- +
Skip to content

The Game Dev Tree changelog:

v1.0.4 Version Bump [rebalanced,debuggedx3] - 2020-11-09

  • Fixed refactorings 2, 3, and 4 not actually affecting productivity

v1.0.3 Version Bump [rebalanced,debuggedx2] - 2020-11-08

  • Fixed API milestone 4 not working

v1.0.2 Version Bump [rebalanced,debugged] - 2020-11-08

  • Fixed tree lines being hidden after hitting "keepGoing" in the victory screen

v1.0.1 Version Bump [rebalanced] - 2020-11-08

  • Buffed several TAs

v1.0 Version Bump - 2020-11-08

  • Finished row 4
  • Added colored text to lore
  • Fixed some visual bugs with milestones
  • Probably other stuff lol its been a week

v0.2.3 Stylish - 2020-10-30

  • Re-styled basically everything
  • Added favicon
  • Added header bar
  • Added changelog

v0.2.2 Row 3 - 2020-10-22

  • Removed debug statement
  • Moved milestones in F layer beneath the buyables

v0.2.1 Row 3 - 2020-10-21

  • Fixed layers hiding
  • Fixed typos/minor issues
  • Fixed S layer being highlighted before you can unlock the layer

v0.2 Row 3 - 2020-10-21

  • Implemented row 3

v0.1.1 Cash Influx [rebalanced] - 2020-10-19

  • Fixed notification issue
  • Rebalanced to make early game faster and late game slower
  • Fixed other minor issues

v0.1 Cash Influx - 2020-10-19

  • Implemented row 2

v0.0 Initial Commit - 2020-10-18

  • Implemented row 1
+ \ No newline at end of file diff --git a/public/gamedevtree/docs/!general-info.html b/public/gamedevtree/docs/!general-info.html index ab6086df7..5b8069d2b 100644 --- a/public/gamedevtree/docs/!general-info.html +++ b/public/gamedevtree/docs/!general-info.html @@ -6,12 +6,12 @@ The-Modding-Tree | The Paper Pilot - + - + - + @@ -50,8 +50,8 @@ -
Skip to content

The-Modding-Tree

The main way to add content is through creating layers. You can either add a layer directly in the layers object in layersSupportjs, or declare it in another file and then do "addLayer(layername, layerdata)" (good for breaking things up into smaller files). The existing layers are just examples and can be freely deleted. You can also use them as references and a base for your own layers.

The first thing you need to do is to edit the modInfo at the top of game.js to set your modID (a string). A unique modId will prevent your mod's saves from conflicting with other mods.

Most of the time, you won't need to dive deep into the code to create things, but you still can if you really want to.

The Modding Tree uses break_eternity.js to store large values. This means that many numbers are Decimal objects, and must be treated differently. For example, you have to use new Decimal(x) to create a Decimal value instead of a plain number, and perform operations on them by calling functions. e.g, instead of x = x + y, use x = x.add(y).

Almost all values can be either a constant value, or a dynamic value. Dynamic values are defined by putting a function that returns what the value should be at any given time.

All display text can be basic HTML instead (But you can't use most Vue features there).

Table of Contents:

General:

  • Getting Started: Getting your own copy of the code set up with Github Desktop.
  • Main mod info: How to set up general things for your mod in mod.js.
  • Basic layer breakdown: Breaking down the components of a layer with minimal features.
  • Layer features: Explanations of all of the different properties that you can give a layer.
  • Custom Tab Layouts: An optional way to give your tabs a different layout. You can even create entirely new components to use.
  • Updating TMT: Using Github Desktop to update your mod's version of TMT.

Common components

  • Upgrades: How to create upgrades for a layer.
  • Milestones: How to create milestones for a layer.
  • Buyables: Create rebuyable upgrades for your layer (with the option to make them respec-able). Can be used to make Enhancers or Space Buildings.
  • Clickables: A more generalized variant of buyables, for any kind of thing that is sometimes clickable. Between these and Buyables, you can do just about anything.

Other components

  • Challenges: How to create challenges for a layer.
  • Bars: Display some information as a progress bar, gague, or similar. They are highly customizable, and can be horizontal and vertical as well.
  • Subtabs and Microtabs: Create subtabs for your tabs, as well as "microtab" components that you can put inside the tabs.
  • Achievements: How to create achievements for a layer (or for the whole game).
  • Infoboxes: Boxes containing text that can be shown or hidden.
- +
Skip to content

The-Modding-Tree

The main way to add content is through creating layers. You can either add a layer directly in the layers object in layersSupportjs, or declare it in another file and then do "addLayer(layername, layerdata)" (good for breaking things up into smaller files). The existing layers are just examples and can be freely deleted. You can also use them as references and a base for your own layers.

The first thing you need to do is to edit the modInfo at the top of game.js to set your modID (a string). A unique modId will prevent your mod's saves from conflicting with other mods.

Most of the time, you won't need to dive deep into the code to create things, but you still can if you really want to.

The Modding Tree uses break_eternity.js to store large values. This means that many numbers are Decimal objects, and must be treated differently. For example, you have to use new Decimal(x) to create a Decimal value instead of a plain number, and perform operations on them by calling functions. e.g, instead of x = x + y, use x = x.add(y).

Almost all values can be either a constant value, or a dynamic value. Dynamic values are defined by putting a function that returns what the value should be at any given time.

All display text can be basic HTML instead (But you can't use most Vue features there).

Table of Contents:

General:

  • Getting Started: Getting your own copy of the code set up with Github Desktop.
  • Main mod info: How to set up general things for your mod in mod.js.
  • Basic layer breakdown: Breaking down the components of a layer with minimal features.
  • Layer features: Explanations of all of the different properties that you can give a layer.
  • Custom Tab Layouts: An optional way to give your tabs a different layout. You can even create entirely new components to use.
  • Updating TMT: Using Github Desktop to update your mod's version of TMT.

Common components

  • Upgrades: How to create upgrades for a layer.
  • Milestones: How to create milestones for a layer.
  • Buyables: Create rebuyable upgrades for your layer (with the option to make them respec-able). Can be used to make Enhancers or Space Buildings.
  • Clickables: A more generalized variant of buyables, for any kind of thing that is sometimes clickable. Between these and Buyables, you can do just about anything.

Other components

  • Challenges: How to create challenges for a layer.
  • Bars: Display some information as a progress bar, gague, or similar. They are highly customizable, and can be horizontal and vertical as well.
  • Subtabs and Microtabs: Create subtabs for your tabs, as well as "microtab" components that you can put inside the tabs.
  • Achievements: How to create achievements for a layer (or for the whole game).
  • Infoboxes: Boxes containing text that can be shown or hidden.
+ \ No newline at end of file diff --git a/public/gamedevtree/docs/achievements.html b/public/gamedevtree/docs/achievements.html index 8de7d970a..c1b33d0d8 100644 --- a/public/gamedevtree/docs/achievements.html +++ b/public/gamedevtree/docs/achievements.html @@ -6,12 +6,12 @@ Achievements | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
Skip to content

Achievements

Achievements are awarded to the player when they meet a certain goal, and give some benefit. Currently, they are pretty basic, but additional features will be added later to help.

You can make global achievements by putting them in a side layer (make its row "side" instead of a number)

Useful functions for dealing with achievements and implementing their effects:

  • hasAchievement(layer, id): determine if the player has the Achievement
  • achievementEffect(layer, id): Returns the current effects of the achievement, if any

Achievements should be formatted like this:

js
    achievements: {
+    
Skip to content

Achievements

Achievements are awarded to the player when they meet a certain goal, and give some benefit. Currently, they are pretty basic, but additional features will be added later to help.

You can make global achievements by putting them in a side layer (make its row "side" instead of a number)

Useful functions for dealing with achievements and implementing their effects:

  • hasAchievement(layer, id): determine if the player has the Achievement
  • achievementEffect(layer, id): Returns the current effects of the achievement, if any

Achievements should be formatted like this:

js
    achievements: {
         rows: # of rows
         cols: # of columns
         11: {
@@ -58,8 +58,8 @@
             more features
         }
         etc
-    }

Each achievement should have an id where the first digit is the row and the second digit is the column. Individual achievement can have these features:

  • name: optional, displayed at the top of the achievement. The only visible text. It can also be a function that returns updating text. Can use basic HTML.

  • done(): A function returning a boolean to determine if the achievement should be awarded.

  • tooltip: Default tooltip for the achievement, appears when it is hovered over. Should convey the goal and any reward for completing the achievement. It can also be a function that returns updating text. Can use basic HTML.

  • effect(): optional, A function that calculates and returns the current values of any bonuses from the achievement. Can return a value or an object containing multiple values.

  • unlocked(): optional, A function returning a bool to determine if the achievement is visible or not. Default is unlocked.

  • onComplete() - optional, this function will be called when the achievement is completed.

  • style: Optional, Applies CSS to this achievement, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings)

  • layer: Assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar

  • id: Assigned automagically. It's the "key" which the achievement was stored under, for convenient access. The achievement in the example's id is 11.

  • goalTooltip: optional, depracated Appears when the achievement is hovered over and locked, overrides the basic tooltip. This is to display the goal (or a hint). It can also be a function that returns updating text. Can use basic HTML.

  • doneTooltip: optional, depracated Appears when the achievement is hovered over and completed, overrides the basic tooltip. This can display what the player achieved (the goal), and the rewards, if any. It can also be a function that returns updating text. Can use basic HTML.

- + }

Each achievement should have an id where the first digit is the row and the second digit is the column. Individual achievement can have these features:

  • name: optional, displayed at the top of the achievement. The only visible text. It can also be a function that returns updating text. Can use basic HTML.

  • done(): A function returning a boolean to determine if the achievement should be awarded.

  • tooltip: Default tooltip for the achievement, appears when it is hovered over. Should convey the goal and any reward for completing the achievement. It can also be a function that returns updating text. Can use basic HTML.

  • effect(): optional, A function that calculates and returns the current values of any bonuses from the achievement. Can return a value or an object containing multiple values.

  • unlocked(): optional, A function returning a bool to determine if the achievement is visible or not. Default is unlocked.

  • onComplete() - optional, this function will be called when the achievement is completed.

  • style: Optional, Applies CSS to this achievement, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings)

  • layer: Assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar

  • id: Assigned automagically. It's the "key" which the achievement was stored under, for convenient access. The achievement in the example's id is 11.

  • goalTooltip: optional, depracated Appears when the achievement is hovered over and locked, overrides the basic tooltip. This is to display the goal (or a hint). It can also be a function that returns updating text. Can use basic HTML.

  • doneTooltip: optional, depracated Appears when the achievement is hovered over and completed, overrides the basic tooltip. This can display what the player achieved (the goal), and the rewards, if any. It can also be a function that returns updating text. Can use basic HTML.

+ \ No newline at end of file diff --git a/public/gamedevtree/docs/bars.html b/public/gamedevtree/docs/bars.html index 3cf965c62..2423da32c 100644 --- a/public/gamedevtree/docs/bars.html +++ b/public/gamedevtree/docs/bars.html @@ -6,12 +6,12 @@ Bars | The Paper Pilot - + - + - + @@ -50,14 +50,14 @@ -
Skip to content

Bars

Bars let you display information in a more direct way. It can be a progress bar, health bar, capacity gague, or anything else.

Bars are defined like other Big Features:

js
    bars: {
+    
Skip to content

Bars

Bars let you display information in a more direct way. It can be a progress bar, health bar, capacity gague, or anything else.

Bars are defined like other Big Features:

js
    bars: {
         bigBar: {
             display() {return "Blah"},
             etc
         }
         etc
-    }

Features:

  • direction: UP, DOWN, LEFT, or RIGHT (not Strings). Determines the direction that the bar is filled as it progresses. RIGHT means from left to right.

  • width, height: The size in pixels of the bar, but as Numbers (no "px" at the end)

  • progress(): A function that returns the portion of the bar that is filled, from "empty" at 0 to "full" at 1. (Nothing bad happens if the value goes out of these bounds, and it can be a number or Decimal).

  • display(): optional, A function that returns text to be displayed on top of the bar, can use HTML.

  • unlocked(): optional, A function returning a bool to determine if the bar is visible or not. Default is unlocked.

  • baseStyle, fillStyle, borderStyle, textStyle: Optional, Apply CSS to the unfilled portion, filled portion, border, and display text on the bar, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

  • layer: Assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar

  • id: Assigned automagically. It's the "key" which the bar was stored under, for convenient access. The bar in the example's id is "bigBar".

- + }

Features:

  • direction: UP, DOWN, LEFT, or RIGHT (not Strings). Determines the direction that the bar is filled as it progresses. RIGHT means from left to right.

  • width, height: The size in pixels of the bar, but as Numbers (no "px" at the end)

  • progress(): A function that returns the portion of the bar that is filled, from "empty" at 0 to "full" at 1. (Nothing bad happens if the value goes out of these bounds, and it can be a number or Decimal).

  • display(): optional, A function that returns text to be displayed on top of the bar, can use HTML.

  • unlocked(): optional, A function returning a bool to determine if the bar is visible or not. Default is unlocked.

  • baseStyle, fillStyle, borderStyle, textStyle: Optional, Apply CSS to the unfilled portion, filled portion, border, and display text on the bar, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

  • layer: Assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar

  • id: Assigned automagically. It's the "key" which the bar was stored under, for convenient access. The bar in the example's id is "bigBar".

+ \ No newline at end of file diff --git a/public/gamedevtree/docs/basic-layer-breakdown.html b/public/gamedevtree/docs/basic-layer-breakdown.html index 3e7ee5815..785d99893 100644 --- a/public/gamedevtree/docs/basic-layer-breakdown.html +++ b/public/gamedevtree/docs/basic-layer-breakdown.html @@ -6,12 +6,12 @@ Basic layer breakdown | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
Skip to content

Basic layer breakdown

This is a very minimal layer with minimal features. Most things will require additional features.

js
    p: {
+    
Skip to content

Basic layer breakdown

This is a very minimal layer with minimal features. Most things will require additional features.

js
    p: {
         startData() { return {                  // startData is a function that returns default data for a layer. 
             unlocked: false,                    // You can add more variables here to add them to your layer.
             points: new Decimal(0),             // "points" is the internal name for the main resource of the layer.
@@ -77,8 +77,8 @@
         },
 
         layerShown() {return true},             // Returns a bool for if this layer's node should be visible in the tree.
-    },
- + },
+ \ No newline at end of file diff --git a/public/gamedevtree/docs/buyables.html b/public/gamedevtree/docs/buyables.html index 28c220f74..a3720b6f5 100644 --- a/public/gamedevtree/docs/buyables.html +++ b/public/gamedevtree/docs/buyables.html @@ -6,12 +6,12 @@ Buyables | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
Skip to content

Buyables

Buyables are usually things that can be bought multiple times with scaling costs. If you set a respec function, the player can reset the purchases to get their currency back.

The amount of a buyable owned is a Decimal. You can get or set the amount of a buyable with getBuyableAmt(layer, id) and setBuyableAmt(layer, id, amt). You can use buyableEffect(layer, id) to get the current effects of a buyable.

Buyables should be formatted like this:

js
    buyables: {
+    
Skip to content

Buyables

Buyables are usually things that can be bought multiple times with scaling costs. If you set a respec function, the player can reset the purchases to get their currency back.

The amount of a buyable owned is a Decimal. You can get or set the amount of a buyable with getBuyableAmt(layer, id) and setBuyableAmt(layer, id, amt). You can use buyableEffect(layer, id) to get the current effects of a buyable.

Buyables should be formatted like this:

js
    buyables: {
         rows: # of rows
         cols: # of columns
         respec() {}, //**optional**, implement it to reset things and give back your currency.
@@ -63,8 +63,8 @@
             etc
         }
         etc
-    }

Features:

  • title: optional, displayed at the top in a larger font It can also be a function that returns updating text.

  • cost(): cost for buying the next buyable. Can have an optional argument "x" to calculate the cost of the x+1th object, but needs to use "current amount" as a default value for x. (x is a Decimal). Can return an object if there are multiple currencies.

  • effect(): optional, A function that calculates and returns the current values of bonuses of this buyable. Can return a value or an object containing multiple values.

  • display(): A function returning everything that should be displayed on the buyable after the title, likely including the description, amount bought, cost, and current effect. Can use basic HTML.

  • unlocked(): optional, A function returning a bool to determine if the buyable is visible or not. Default is unlocked.

  • canAfford(): A function returning a bool to determine if you can buy one of the buyables.

  • buy(): A function that implements buying one of the buyable, including spending the currency.

  • buyMax(): optional, A function that implements buying as many of the buyable as possible.

  • style: Optional, Applies CSS to this buyable, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings)

  • layer: Assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar

  • id: Assigned automagically. It's the "key" which the buyable was stored under, for convenient access. The buyable in the example's id is 11.

Sell One/Sell All:

Including a sellOne or sellAll function will cause an additional button to appear beneath the buyable. They are functionally identical, but "sell one" appears above "sell all". You can also use them for other things.

sellOne/sellAll(): optional, Called when the button is pressed. The standard use would be to decrease/reset the amount of the buyable, And possibly return some currency to the player.

canSellOne/canSellAll(): optional, booleans determining whether or not to show the buttons. If "canSellOne/All" is absent but "sellOne/All" is present, the appropriate button will always show.

- + }

Features:

  • title: optional, displayed at the top in a larger font It can also be a function that returns updating text.

  • cost(): cost for buying the next buyable. Can have an optional argument "x" to calculate the cost of the x+1th object, but needs to use "current amount" as a default value for x. (x is a Decimal). Can return an object if there are multiple currencies.

  • effect(): optional, A function that calculates and returns the current values of bonuses of this buyable. Can return a value or an object containing multiple values.

  • display(): A function returning everything that should be displayed on the buyable after the title, likely including the description, amount bought, cost, and current effect. Can use basic HTML.

  • unlocked(): optional, A function returning a bool to determine if the buyable is visible or not. Default is unlocked.

  • canAfford(): A function returning a bool to determine if you can buy one of the buyables.

  • buy(): A function that implements buying one of the buyable, including spending the currency.

  • buyMax(): optional, A function that implements buying as many of the buyable as possible.

  • style: Optional, Applies CSS to this buyable, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings)

  • layer: Assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar

  • id: Assigned automagically. It's the "key" which the buyable was stored under, for convenient access. The buyable in the example's id is 11.

Sell One/Sell All:

Including a sellOne or sellAll function will cause an additional button to appear beneath the buyable. They are functionally identical, but "sell one" appears above "sell all". You can also use them for other things.

sellOne/sellAll(): optional, Called when the button is pressed. The standard use would be to decrease/reset the amount of the buyable, And possibly return some currency to the player.

canSellOne/canSellAll(): optional, booleans determining whether or not to show the buttons. If "canSellOne/All" is absent but "sellOne/All" is present, the appropriate button will always show.

+ \ No newline at end of file diff --git a/public/gamedevtree/docs/challenges.html b/public/gamedevtree/docs/challenges.html index 66aa861f1..328635009 100644 --- a/public/gamedevtree/docs/challenges.html +++ b/public/gamedevtree/docs/challenges.html @@ -6,12 +6,12 @@ Challenges | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
Skip to content

Challenges

Useful functions for dealing with Challenges and implementing their effects:

  • inChallenge(layer, id): determine if the player is in a given challenge (or another challenge on the same layer that counts as this one)
  • hasChallenge(layer, id): determine if the player has completed the challenge
  • challengeCompletions(layer, id): determine how many times the player completed the challenge
  • challEffect(layer, id): Returns the current effects of the challenge, if any

Challenges are stored in the following format:

js
    challenges: {
+    
Skip to content

Challenges

Useful functions for dealing with Challenges and implementing their effects:

  • inChallenge(layer, id): determine if the player is in a given challenge (or another challenge on the same layer that counts as this one)
  • hasChallenge(layer, id): determine if the player has completed the challenge
  • challengeCompletions(layer, id): determine how many times the player completed the challenge
  • challEffect(layer, id): Returns the current effects of the challenge, if any

Challenges are stored in the following format:

js
    challenges: {
         rows: # of rows
         cols: # of columns
         11: {
@@ -58,8 +58,8 @@
             etc
         }
         etc
-    }

Each challenge should have an id where the first digit is the row and the second digit is the column. Individual Challenges can have these features:

  • name: Name of the challenge, can be a string or a function. Can use basic HTML.

  • challengeDescription: A description of what makes the challenge a challenge. You will need to implement these elsewhere It can also be a function that returns updating text. Can use basic HTML.

  • rewardDescription: A description of the reward's effect. You will also have to implement the effect where it is applied. It can also be a function that returns updating text. Can use basic HTML.

  • rewardEffect(): optional, A function that calculates and returns the current values of any bonuses from the reward. Can return a value or an object containing multiple values. Can use basic HTML.

  • rewardDisplay(): optional, A function that returns a display of the current effects of the reward with formatting. Default behavior is to just display the a number appropriately formatted.

  • goal: A Decimal for the amount of currency required to beat the challenge. By default, the goal is in basic Points. The goal can also be a function if its value changes.

  • unlocked(): optional, A function returning a bool to determine if the challenge is visible or not. Default is unlocked.

  • onComplete() - optional, this function will be called when the challenge is completed when previously incomplete.

  • countsAs: optional, If a challenge combines the effects of other challenges in this layer, you can use this. An array of challenge ids. The player is effectively in all of those challenges when in the current one.

By default, challenges use basic Points for the goal. You can change that using these features.

  • currencyDisplayName: optional, the name to display for the currency for the goal

  • currencyInternalName: optional, the internal name for that currency

  • currencyLayer: optional, the internal name of the layer that currency is stored in. If it's not in a layer, omit. If it's not stored directly in a layer, instead use the next feature.

  • currencyLocation: optional, if your currency is stored in something inside a layer (e.g. a buyable's amount), you can access it this way. This is a function returning the object in "player" that contains the value (like player[this.layer].buyables)

  • completionLimit: optional, the amount of times you can complete this challenge. Default is 1 completion.

  • style: Optional, Applies CSS to this challenge, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings)

  • layer: Assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar

  • id: Assigned automagically. It's the "key" which the challenge was stored under, for convenient access. The challenge in the example's id is 11.

- + }

Each challenge should have an id where the first digit is the row and the second digit is the column. Individual Challenges can have these features:

  • name: Name of the challenge, can be a string or a function. Can use basic HTML.

  • challengeDescription: A description of what makes the challenge a challenge. You will need to implement these elsewhere It can also be a function that returns updating text. Can use basic HTML.

  • rewardDescription: A description of the reward's effect. You will also have to implement the effect where it is applied. It can also be a function that returns updating text. Can use basic HTML.

  • rewardEffect(): optional, A function that calculates and returns the current values of any bonuses from the reward. Can return a value or an object containing multiple values. Can use basic HTML.

  • rewardDisplay(): optional, A function that returns a display of the current effects of the reward with formatting. Default behavior is to just display the a number appropriately formatted.

  • goal: A Decimal for the amount of currency required to beat the challenge. By default, the goal is in basic Points. The goal can also be a function if its value changes.

  • unlocked(): optional, A function returning a bool to determine if the challenge is visible or not. Default is unlocked.

  • onComplete() - optional, this function will be called when the challenge is completed when previously incomplete.

  • countsAs: optional, If a challenge combines the effects of other challenges in this layer, you can use this. An array of challenge ids. The player is effectively in all of those challenges when in the current one.

By default, challenges use basic Points for the goal. You can change that using these features.

  • currencyDisplayName: optional, the name to display for the currency for the goal

  • currencyInternalName: optional, the internal name for that currency

  • currencyLayer: optional, the internal name of the layer that currency is stored in. If it's not in a layer, omit. If it's not stored directly in a layer, instead use the next feature.

  • currencyLocation: optional, if your currency is stored in something inside a layer (e.g. a buyable's amount), you can access it this way. This is a function returning the object in "player" that contains the value (like player[this.layer].buyables)

  • completionLimit: optional, the amount of times you can complete this challenge. Default is 1 completion.

  • style: Optional, Applies CSS to this challenge, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings)

  • layer: Assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar

  • id: Assigned automagically. It's the "key" which the challenge was stored under, for convenient access. The challenge in the example's id is 11.

+ \ No newline at end of file diff --git a/public/gamedevtree/docs/clickables.html b/public/gamedevtree/docs/clickables.html index aca3c3502..fb3f5f19e 100644 --- a/public/gamedevtree/docs/clickables.html +++ b/public/gamedevtree/docs/clickables.html @@ -6,12 +6,12 @@ Clickables | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
Skip to content

Clickables

Clickables are any kind of thing that you can click for an effect. They're a more generalized version of Buyables.

DO NOT USE THESE TO MAKE THINGS THAT YOU CLICK REPEATEDLY FOR A BONUS BECAUSE THOSE ARE AWFUL.

There are several differences between the two. One is that a buyable's saved data is its amount as a Decimal, while Clickables store a "state" which can be a number or string, but not Decimal, array, or object). Buyables have a number of extra features which you can see on their page. Clickables also have a smaller default size.

You can get and set a clickable's state with getClickableState(layer, id) and setClickableState(layer, id, state). You can use clickableEffect(layer, id) to get the current effects of a clickable.

Clickables should be formatted like this:

js
    clickables: {
+    
Skip to content

Clickables

Clickables are any kind of thing that you can click for an effect. They're a more generalized version of Buyables.

DO NOT USE THESE TO MAKE THINGS THAT YOU CLICK REPEATEDLY FOR A BONUS BECAUSE THOSE ARE AWFUL.

There are several differences between the two. One is that a buyable's saved data is its amount as a Decimal, while Clickables store a "state" which can be a number or string, but not Decimal, array, or object). Buyables have a number of extra features which you can see on their page. Clickables also have a smaller default size.

You can get and set a clickable's state with getClickableState(layer, id) and setClickableState(layer, id, state). You can use clickableEffect(layer, id) to get the current effects of a clickable.

Clickables should be formatted like this:

js
    clickables: {
         rows: # of rows
         cols: # of columns
         masterButtonPress() // **optional** If this is present, an additional button will appear above the clickables.
@@ -62,8 +62,8 @@
             etc
         }
         etc
-    }

Features:

  • title: optional, displayed at the top in a larger font It can also be a function that returns updating text.

  • effect(): optional, A function that calculates and returns the current values of bonuses of this clickable. Can return a value or an object containing multiple values.

  • display(): A function returning everything that should be displayed on the clickable after the title, likely changing based on its state. Can use basic HTML.

  • unlocked(): optional, A function returning a bool to determine if the clickable is visible or not. Default is unlocked.

  • canClick(): A function returning a bool to determine if you can click the clickable.

  • onClick(): A function that implements clicking one of the clickable.

  • style: Optional, Applies CSS to this clickable, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings)

  • layer: Assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

  • id: Assigned automagically. It's the "key" which the clickable was stored under, for convenient access. The clickable in the example's id is 11.

- + }

Features:

  • title: optional, displayed at the top in a larger font It can also be a function that returns updating text.

  • effect(): optional, A function that calculates and returns the current values of bonuses of this clickable. Can return a value or an object containing multiple values.

  • display(): A function returning everything that should be displayed on the clickable after the title, likely changing based on its state. Can use basic HTML.

  • unlocked(): optional, A function returning a bool to determine if the clickable is visible or not. Default is unlocked.

  • canClick(): A function returning a bool to determine if you can click the clickable.

  • onClick(): A function that implements clicking one of the clickable.

  • style: Optional, Applies CSS to this clickable, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings)

  • layer: Assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

  • id: Assigned automagically. It's the "key" which the clickable was stored under, for convenient access. The clickable in the example's id is 11.

+ \ No newline at end of file diff --git a/public/gamedevtree/docs/custom-tab-layouts.html b/public/gamedevtree/docs/custom-tab-layouts.html index 1feaaf590..4fde30060 100644 --- a/public/gamedevtree/docs/custom-tab-layouts.html +++ b/public/gamedevtree/docs/custom-tab-layouts.html @@ -6,12 +6,12 @@ Custom tab layouts | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
Skip to content

Custom tab layouts

Note: If you are using subtabs, tabFormat is used differently, but you still use the same format within each subtabs. See here for more on subtabs

Custom tab layouts can be used to do basically anything in a tab window, especially combined with the "style" layer feature. The tabFormat feature is an array of things, like this:

js
    tabFormat: ["main-display",
+    
Skip to content

Custom tab layouts

Note: If you are using subtabs, tabFormat is used differently, but you still use the same format within each subtabs. See here for more on subtabs

Custom tab layouts can be used to do basically anything in a tab window, especially combined with the "style" layer feature. The tabFormat feature is an array of things, like this:

js
    tabFormat: ["main-display",
             ["prestige-button", function(){return "Melt your points into "}],
             "blank",
             ["display-text",
@@ -58,8 +58,8 @@
                 {"color": "red", "font-size": "32px", "font-family": "Comic Sans MS"}],
             "blank",
             ["toggle", ["c", "beep"]],
-            "milestones", "blank", "blank", "upgrades"]

It is a list of components, which can be either just a name, or an array with arguments. If it's an array, the first item is the name of the component, the second is the data passed into it, and the third (optional) applies a CSS style to it with a "CSS object", where the keys are CSS attributes.

These are the existing components, but you can create more in v.js:

  • display-text: Displays some text (can use basic HTML). The argument is the text to display. It can also be a function that returns updating text.

  • raw-html: Displays some basic HTML, can also be a function.

  • blank: Adds empty space. The default dimensions are 8px x 17px. The argument changes the dimensions. If it's a single value (e.g. "20px"), that determines the height. If you have a pair of arguments, the first is width and the second is height.

  • row: Display a list of components horizontally. The argument is an array of components in the tab layout format.

  • column: Display a list of components vertically. The argument is an array of components in the tab layout format. This is useful to display columns within a row.

  • main-display: The text that displays the main currency for the layer and its effects.

  • resource-display: The text that displays the currency that this layer is based on, as well as the best and/or total values for this layer's prestige currency (if they are put in startData for this layer)

  • prestige-button: The argument is a string that the prestige button should say before the amount of currency you will gain. It can also be a function that returns updating text.

  • upgrades, milestones, challs, achievements: Display the upgrades, milestones, and challenges for a layer, as appropriate.

  • buyables, clickables: Display all of the buyables/clickables for this layer, as appropriate. The argument optional, and is the size of the boxes in pixels.

  • microtabs: Display a set of subtabs for an area. The argument is the name of the set of microtabs in the "microtabs" feature.

  • bar: Display a bar. The argument is the id of the bar to display.

  • infobox: Display an infobox. The argument is the id of the infobox to display.

  • toggle: A toggle button that toggles a bool value. The data is a pair that identifies what bool to toggle, [layer, id]

The rest of the components are sub-components. They can be used just like other components, but are typically part of another component.

  • upgrade, milestone, chall, buyable, clickable, achievement: An individual upgrade, challenge, etc. The argument is the id. This can be used if you want to have upgrades split up across multiple subtabs, for example.

  • respec-button, master-button: The respec and master buttons for buyables and clickables, respectively.

  • sell-one, sell-all: The "sell one" and "sell all" for buyables, respectively. The argument is the id of the buyable.

- + "milestones", "blank", "blank", "upgrades"]

It is a list of components, which can be either just a name, or an array with arguments. If it's an array, the first item is the name of the component, the second is the data passed into it, and the third (optional) applies a CSS style to it with a "CSS object", where the keys are CSS attributes.

These are the existing components, but you can create more in v.js:

  • display-text: Displays some text (can use basic HTML). The argument is the text to display. It can also be a function that returns updating text.

  • raw-html: Displays some basic HTML, can also be a function.

  • blank: Adds empty space. The default dimensions are 8px x 17px. The argument changes the dimensions. If it's a single value (e.g. "20px"), that determines the height. If you have a pair of arguments, the first is width and the second is height.

  • row: Display a list of components horizontally. The argument is an array of components in the tab layout format.

  • column: Display a list of components vertically. The argument is an array of components in the tab layout format. This is useful to display columns within a row.

  • main-display: The text that displays the main currency for the layer and its effects.

  • resource-display: The text that displays the currency that this layer is based on, as well as the best and/or total values for this layer's prestige currency (if they are put in startData for this layer)

  • prestige-button: The argument is a string that the prestige button should say before the amount of currency you will gain. It can also be a function that returns updating text.

  • upgrades, milestones, challs, achievements: Display the upgrades, milestones, and challenges for a layer, as appropriate.

  • buyables, clickables: Display all of the buyables/clickables for this layer, as appropriate. The argument optional, and is the size of the boxes in pixels.

  • microtabs: Display a set of subtabs for an area. The argument is the name of the set of microtabs in the "microtabs" feature.

  • bar: Display a bar. The argument is the id of the bar to display.

  • infobox: Display an infobox. The argument is the id of the infobox to display.

  • toggle: A toggle button that toggles a bool value. The data is a pair that identifies what bool to toggle, [layer, id]

The rest of the components are sub-components. They can be used just like other components, but are typically part of another component.

  • upgrade, milestone, chall, buyable, clickable, achievement: An individual upgrade, challenge, etc. The argument is the id. This can be used if you want to have upgrades split up across multiple subtabs, for example.

  • respec-button, master-button: The respec and master buttons for buyables and clickables, respectively.

  • sell-one, sell-all: The "sell one" and "sell all" for buyables, respectively. The argument is the id of the buyable.

+ \ No newline at end of file diff --git a/public/gamedevtree/docs/getting-started.html b/public/gamedevtree/docs/getting-started.html index 42daad850..d7981457a 100644 --- a/public/gamedevtree/docs/getting-started.html +++ b/public/gamedevtree/docs/getting-started.html @@ -6,12 +6,12 @@ Getting started | The Paper Pilot - + - + - + @@ -50,8 +50,8 @@ -
Skip to content

Getting started

Welcome to The Modding Tree!

Using the Modding Tree, at its simplest level, just requires getting a copy of it onto your computer. However, if you do it the right way, it will help in many ways.

Don't let the word "Github" scare you away. It's actually much easier to use than most people think, especially because most people use it the hard way. The key is Github Desktop, which lets you do everything you need to, without even touching the command line.

The benefits of using Github:

  • It makes it much, much easier to update The Modding Tree.
  • You can share your work without any extra effort using githack, or with a bit more effort, set up a github.io site.
  • It lets you undo changes to your code, and to have multiple versions of it.
  • It lets you collaborate with other people, if you want to.

Getting set up with Github and The Modding Tree:

  1. Install Github Desktop and Visual Studio Code.

  2. Make a Github account. You can handle this on your own.

  3. Log in on your browser, and go back to The Modding Tree page. At the top right, there should be a button that says "fork". Click on it, and then on your username. You now have your own fork, or copy, of The Modding Tree.

  4. Open Github Desktop and log in. Ignore everything else and choose "clone a repository". A "repository" is basically a "Github project", like The Modding Tree. "Cloning" is downloading a copy of the repository to your computer.

  5. Look for The Modding Tree in the list of repositiories (it should be the only one) and click "clone".

  6. Select that you're using it for your own purposes, and click continue. It will download the files and handle everything.

Using your repository

  1. Click on "show in finder" to the right, and then open index.html. This will let you view and test your project!

  2. To edit your project, click "open in VSCode" in Github Desktop.

  3. Open mod.js in VSCode, and look at the top part where it says "modInfo". On the lines below that, change the mod's name to whatever you want, and change the id as well. (It can be any string value, and it's used to determine where the savefile is. Make it something that's probably unique, and don't change it again later.)

  4. Save game.js, and then reload index.html. The title on the tab, as well as on the info page, will now be the new ones!

  5. Go back to Github Desktop. It's time to save your changes into the git system by making a "commit".

  6. At the bottom right corner, add a summary of your changes, and then click "commit to master".

  7. Finally, at the top middle, click "push origin" to push your changes out onto the online repository.

  8. You can view your project on line, or share it with others, by going to https://raw.githack.com/[YOUR-GITHUB-USERNAME]/The-Modding-Tree/master/index.html

And now, you have successfully used Github! You can look at the documentation to see how The Modding Tree's system works and to make your mod a reality.

- +
Skip to content

Getting started

Welcome to The Modding Tree!

Using the Modding Tree, at its simplest level, just requires getting a copy of it onto your computer. However, if you do it the right way, it will help in many ways.

Don't let the word "Github" scare you away. It's actually much easier to use than most people think, especially because most people use it the hard way. The key is Github Desktop, which lets you do everything you need to, without even touching the command line.

The benefits of using Github:

  • It makes it much, much easier to update The Modding Tree.
  • You can share your work without any extra effort using githack, or with a bit more effort, set up a github.io site.
  • It lets you undo changes to your code, and to have multiple versions of it.
  • It lets you collaborate with other people, if you want to.

Getting set up with Github and The Modding Tree:

  1. Install Github Desktop and Visual Studio Code.

  2. Make a Github account. You can handle this on your own.

  3. Log in on your browser, and go back to The Modding Tree page. At the top right, there should be a button that says "fork". Click on it, and then on your username. You now have your own fork, or copy, of The Modding Tree.

  4. Open Github Desktop and log in. Ignore everything else and choose "clone a repository". A "repository" is basically a "Github project", like The Modding Tree. "Cloning" is downloading a copy of the repository to your computer.

  5. Look for The Modding Tree in the list of repositiories (it should be the only one) and click "clone".

  6. Select that you're using it for your own purposes, and click continue. It will download the files and handle everything.

Using your repository

  1. Click on "show in finder" to the right, and then open index.html. This will let you view and test your project!

  2. To edit your project, click "open in VSCode" in Github Desktop.

  3. Open mod.js in VSCode, and look at the top part where it says "modInfo". On the lines below that, change the mod's name to whatever you want, and change the id as well. (It can be any string value, and it's used to determine where the savefile is. Make it something that's probably unique, and don't change it again later.)

  4. Save game.js, and then reload index.html. The title on the tab, as well as on the info page, will now be the new ones!

  5. Go back to Github Desktop. It's time to save your changes into the git system by making a "commit".

  6. At the bottom right corner, add a summary of your changes, and then click "commit to master".

  7. Finally, at the top middle, click "push origin" to push your changes out onto the online repository.

  8. You can view your project on line, or share it with others, by going to https://raw.githack.com/[YOUR-GITHUB-USERNAME]/The-Modding-Tree/master/index.html

And now, you have successfully used Github! You can look at the documentation to see how The Modding Tree's system works and to make your mod a reality.

+ \ No newline at end of file diff --git a/public/gamedevtree/docs/infoboxes.html b/public/gamedevtree/docs/infoboxes.html index 945204efe..426bc6d6f 100644 --- a/public/gamedevtree/docs/infoboxes.html +++ b/public/gamedevtree/docs/infoboxes.html @@ -6,12 +6,12 @@ Infoboxes | The Paper Pilot - + - + - + @@ -50,14 +50,14 @@ -
Skip to content

Infoboxes

Infoboxes are good for displaying "lore", or story elements, as well as for explaining complicated things.

In the default tab layout, the first infobox will be displayed at the very top of the tab.

Infoboxes are defined like other Big Features:

js
    infoboxes: {
+    
Skip to content

Infoboxes

Infoboxes are good for displaying "lore", or story elements, as well as for explaining complicated things.

In the default tab layout, the first infobox will be displayed at the very top of the tab.

Infoboxes are defined like other Big Features:

js
    infoboxes: {
         infobox: {
             display() {return "Blah"},
             etc
         }
         etc
-    }

Features:

  • title: The text displayed above the main box. Can be a function to be dynamic, and can use basic HTML.

  • body: The text displayed inside the box. Can be a function to be dynamic, and can use basic HTML.

  • style, titleStyle, bodyStyle: Optional, Apply CSS to the infobox, or to the title button or body of the infobox, in the form of an object where the keys are CSS attributes, and the values are the Values for those attributes (both as strings).

  • unlocked(): optional, A function returning a bool to determine if the infobox is visible or not. Default is unlocked.

  • layer: Assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar

  • id: Assigned automagically. It's the "key" which the bar was stored under, for convenient access. The bar in the example's id is "bigBar".

- + }

Features:

  • title: The text displayed above the main box. Can be a function to be dynamic, and can use basic HTML.

  • body: The text displayed inside the box. Can be a function to be dynamic, and can use basic HTML.

  • style, titleStyle, bodyStyle: Optional, Apply CSS to the infobox, or to the title button or body of the infobox, in the form of an object where the keys are CSS attributes, and the values are the Values for those attributes (both as strings).

  • unlocked(): optional, A function returning a bool to determine if the infobox is visible or not. Default is unlocked.

  • layer: Assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar

  • id: Assigned automagically. It's the "key" which the bar was stored under, for convenient access. The bar in the example's id is "bigBar".

+ \ No newline at end of file diff --git a/public/gamedevtree/docs/layer-features.html b/public/gamedevtree/docs/layer-features.html index c13370c37..2f52bd4bc 100644 --- a/public/gamedevtree/docs/layer-features.html +++ b/public/gamedevtree/docs/layer-features.html @@ -6,12 +6,12 @@ Layer Features | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
Skip to content

Layer Features

This is a more comprehensive list of established features to add to layers. You can add more freely, if you want to have other functions or values associated with your layer. These have special functionality, though.

You can make almost any value dynamic by using a function in its place, including all display strings and styling/color features.

Key:

  • No label: This is required and the game will crash if it isn't included.
  • sometimes required: This is may be required, depending on other things in the layer.
  • optional: You can leave this out if you don't intend to use that feature for the layer.

Layer Definition features

  • layer: Assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar to access the save value. It makes copying code to new layers easier. It is also assigned to all upgrades and buyables and such.

  • name: Optional, used in reset confirmations (and maybe other places). If absent, it just uses the layer's id.

  • startData(): A function to return the default save data for this layer. Add any variables you have to it. Any nonstandard Decimal variables need to be added to convertToDecimal as well. Standard values: Required: unlocked: a bool determining if this layer is unlocked or not points: a Decimal, the main currency for the layer Optional: total: A Decimal, tracks total amount of main prestige currency best: A Decimal, tracks highest amount of main prestige currency unlockOrder: used to keep track of relevant layers unlocked before this one.

  • color: A color associated with this layer, used in many places. (A string in hex format with a #)

  • row: The row of the layer, starting at 0. This affects where the node appears on the tree, and which resets affect the layer.

     Using "side" instead of a number will cause the layer to appear off to the side as a smaller node (useful for achievements
    +    
    Skip to content

    Layer Features

    This is a more comprehensive list of established features to add to layers. You can add more freely, if you want to have other functions or values associated with your layer. These have special functionality, though.

    You can make almost any value dynamic by using a function in its place, including all display strings and styling/color features.

    Key:

    • No label: This is required and the game will crash if it isn't included.
    • sometimes required: This is may be required, depending on other things in the layer.
    • optional: You can leave this out if you don't intend to use that feature for the layer.

    Layer Definition features

    • layer: Assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar to access the save value. It makes copying code to new layers easier. It is also assigned to all upgrades and buyables and such.

    • name: Optional, used in reset confirmations (and maybe other places). If absent, it just uses the layer's id.

    • startData(): A function to return the default save data for this layer. Add any variables you have to it. Any nonstandard Decimal variables need to be added to convertToDecimal as well. Standard values: Required: unlocked: a bool determining if this layer is unlocked or not points: a Decimal, the main currency for the layer Optional: total: A Decimal, tracks total amount of main prestige currency best: A Decimal, tracks highest amount of main prestige currency unlockOrder: used to keep track of relevant layers unlocked before this one.

    • color: A color associated with this layer, used in many places. (A string in hex format with a #)

    • row: The row of the layer, starting at 0. This affects where the node appears on the tree, and which resets affect the layer.

       Using "side" instead of a number will cause the layer to appear off to the side as a smaller node (useful for achievements
        and statistics). Side layers are not affected by resets unless you add a doReset to them.
       
    • resource: Name of the main currency you gain by resetting on this layer.

    • effect(): optional, A function that calculates and returns the current values of any bonuses inherent to the main currency. Can return a value or an object containing multiple values. You will also have to implement the effect where it is applied.

    • effectDescription: optional, A function that returns a description of this effect. If the text stays constant, it can just be a string.

    • layerShown(): A function returning a bool which determines if this layer's node should be visible on the tree. It can also return "ghost", which will hide the layer, but its node will still take up space in the tree.

    • hotkeys: optional, An array containing information on any hotkeys associated with this layer:

      js
      hotkeys: [
           {key: "p", // What the hotkey button is. Use uppercase if it's combined with shift, or "ctrl+x" if ctrl is.
      @@ -65,8 +65,8 @@
       
    • update(diff): optional, this function is called every game tick. Use it for any passive resource production or time-based things. diff is the time since the last tick. Suggestion: use addPoints(layer, gain) when generating points to automatically update the best and total amounts.

    • automate(): optional, this function is called every game tick, after production. Use it to activate any autobuyers or auto-resets or similar on this layer, if appropriate.

    • resetsNothing: optional, returns true if this layer shouldn't trigger any resets when you prestige.

    • increaseUnlockOrder: optional, an array of layer ids. When this layer is unlocked for the first time, the unlockOrder value for any not-yet-unlocked layers in this list increases. This can be used to make them harder to unlock.

    • shouldNotify: optional, a function to return true if this layer should be highlighted in the tree. The layer will automatically be highlighted if you can buy an upgrade whether you have this or not.

    • componentStyles: optional, An object that contains a set of functions returning CSS objects. Each of these will be applied to any components on the layer with the type of its id. Example:

    js
            componentStyles: {
                 "challenge"() {return {'height': '200px'}},
                 "prestige-button"() {return {'color': '#AA66AA'}},
    -        },

    Custom Prestige type

    • getResetGain(): For custom prestige type, Returns how many points you should get if you reset now. You can call getResetGain(this.layer, useType = "static") or similar to calculate what your gain would be under another prestige type (provided you have all of the required features in the layer.)

    • getNextAt(canMax=false): For custom prestige type, Returns how many of the base currency you need to get to the next point. canMax is an optional variable used with Static-ish layers to differentiate between if it's looking for the first point you can reset at, or the requirement for any gain at all. (Supporting both is good). You can also call getNextAt(this.layer, canMax=false, useType = "static") or similar to calculate what your next at would be under another prestige type (provided you have all of the required features in the layer.)

    • canReset(): For custom prestige type, return true only if you have the resources required to do a prestige here.

    - + },

Custom Prestige type

  • getResetGain(): For custom prestige type, Returns how many points you should get if you reset now. You can call getResetGain(this.layer, useType = "static") or similar to calculate what your gain would be under another prestige type (provided you have all of the required features in the layer.)

  • getNextAt(canMax=false): For custom prestige type, Returns how many of the base currency you need to get to the next point. canMax is an optional variable used with Static-ish layers to differentiate between if it's looking for the first point you can reset at, or the requirement for any gain at all. (Supporting both is good). You can also call getNextAt(this.layer, canMax=false, useType = "static") or similar to calculate what your next at would be under another prestige type (provided you have all of the required features in the layer.)

  • canReset(): For custom prestige type, return true only if you have the resources required to do a prestige here.

+ \ No newline at end of file diff --git a/public/gamedevtree/docs/main-mod-info.html b/public/gamedevtree/docs/main-mod-info.html index f5d603ab5..ac128b95f 100644 --- a/public/gamedevtree/docs/main-mod-info.html +++ b/public/gamedevtree/docs/main-mod-info.html @@ -6,12 +6,12 @@ mod.js | The Paper Pilot - + - + - + @@ -50,12 +50,12 @@ -
Skip to content

mod.js

All of the code and data that you're likely to edit is here in mod.js! Everything in mod.js will not be altered by updates, besides the addition of new things.

Here's a breakdown of what's in it:

  • modInfo is where most of the basic configuration for the mod is. It contains:

    • name: The name of your mod. (a string)
    • id: The id for your mod, a unique string that is used to determine savefile location. Setting it is important!
    • author: The name of the author, displayed in the info tab.
    • pointsName: This changes what is displayed instead of "points" for the main currency. (It does not affect it in the code.)
    • discordName, discordLink: If you have a Discord server or other discussion place, you can add a link to it. "discordName" is the text on the link, and "discordLink" is the url of an invite. If you're using a Discord invite, please make sure it's set to never expire.
    • changelogLink: You can use this to set a link to a page where your changelog for the game is displayed.
    • offlineLimit: The maximum amount of offline time that the player can accumulate, in hours. Any extra time is lost. (a number) This is useful because most of these mods are fast-paced enough that too much offline time ruins the balance, such as the time in between updates. That is why I suggest developers disable offline time on their own savefile.
    • initialStartPoints: A Decimal for the amount of points a new player should start with.
  • VERSION is used to describe the current version of your mod. It contains: num: The mod's version number, displayed at the top right of the tree tab. name: The version's name, displayed alongside the number in the info tab.

  • doNotCallTheseFunctionsEveryTick is very important. TMT calls every function anywhere in "layers" every tick to store the result, unless specifically told not to. Functions that have are used to do an action need to be identified. "Official" functions (those in the documentation) are all fine, but if you make any new ones, add their names to this array.

js
// (The ones here are examples, all official functions are already taken care of)
+    
Skip to content

mod.js

All of the code and data that you're likely to edit is here in mod.js! Everything in mod.js will not be altered by updates, besides the addition of new things.

Here's a breakdown of what's in it:

  • modInfo is where most of the basic configuration for the mod is. It contains:

    • name: The name of your mod. (a string)
    • id: The id for your mod, a unique string that is used to determine savefile location. Setting it is important!
    • author: The name of the author, displayed in the info tab.
    • pointsName: This changes what is displayed instead of "points" for the main currency. (It does not affect it in the code.)
    • discordName, discordLink: If you have a Discord server or other discussion place, you can add a link to it. "discordName" is the text on the link, and "discordLink" is the url of an invite. If you're using a Discord invite, please make sure it's set to never expire.
    • changelogLink: You can use this to set a link to a page where your changelog for the game is displayed.
    • offlineLimit: The maximum amount of offline time that the player can accumulate, in hours. Any extra time is lost. (a number) This is useful because most of these mods are fast-paced enough that too much offline time ruins the balance, such as the time in between updates. That is why I suggest developers disable offline time on their own savefile.
    • initialStartPoints: A Decimal for the amount of points a new player should start with.
  • VERSION is used to describe the current version of your mod. It contains: num: The mod's version number, displayed at the top right of the tree tab. name: The version's name, displayed alongside the number in the info tab.

  • doNotCallTheseFunctionsEveryTick is very important. TMT calls every function anywhere in "layers" every tick to store the result, unless specifically told not to. Functions that have are used to do an action need to be identified. "Official" functions (those in the documentation) are all fine, but if you make any new ones, add their names to this array.

js
// (The ones here are examples, all official functions are already taken care of)
 var doNotCallTheseFunctionsEveryTick = ["doReset", "buy", "onPurchase", "blowUpEverything"]
  • getStartPoints(): A function to determine the amount of points the player starts with after a reset. (returns a Decimal value)

  • canGenPoints(): A function returning a boolean for if points should be generated. Use this if you want an upgrade to unlock generating points.

  • getPointGen(): A function that calculates your points per second. Anything that affects your point gain should go into the calculation here.

  • addedPlayerData(): A function that returns any non-layer-related data that you want to be added to the save data and "player" object.

js
function addedPlayerData() { return {
 	weather: "Yes",
 	happiness: new Decimal(72),
-}}
  • displayThings: An array of functions used to display extra things at the top of the tree tab. Each function returns a string, which is a line to display (with basic HTML support). If a function returns nothing, nothing is displayed (and it doesn't take up a line).

  • isEndgame(): A function to determine if the player has reached the end of the game, at which point the "you win!" screen appears.

Less important things beyond this point!

  • maxTickLength(): Returns the maximum tick length, in milliseconds. Only really useful if you have something that reduces over time, which long ticks mess up (usually a challenge).
- +}}
  • displayThings: An array of functions used to display extra things at the top of the tree tab. Each function returns a string, which is a line to display (with basic HTML support). If a function returns nothing, nothing is displayed (and it doesn't take up a line).

  • isEndgame(): A function to determine if the player has reached the end of the game, at which point the "you win!" screen appears.

Less important things beyond this point!

  • maxTickLength(): Returns the maximum tick length, in milliseconds. Only really useful if you have something that reduces over time, which long ticks mess up (usually a challenge).
+ \ No newline at end of file diff --git a/public/gamedevtree/docs/milestones.html b/public/gamedevtree/docs/milestones.html index ba84ebcf0..19cd654a7 100644 --- a/public/gamedevtree/docs/milestones.html +++ b/public/gamedevtree/docs/milestones.html @@ -6,12 +6,12 @@ Milestones | The Paper Pilot - + - + - + @@ -50,14 +50,14 @@ -
Skip to content

Milestones

Milestones are awarded to the player when they meet a certain goal, and give some benefit. Milestones should be formatted like this:

js
    milestones: {
+    
Skip to content

Milestones

Milestones are awarded to the player when they meet a certain goal, and give some benefit. Milestones should be formatted like this:

js
    milestones: {
         0: {
             requirementDesc: "123 waffles",
         }
         etc
     }

You can use hasMilestone(layer, id) to determine if the player has a given milestone

Milestone features:

  • requirementDesc: A string describing the requirement for unlocking this milestone. Suggestion: Use a "total". It can also be a function that returns updating text. Can use basic HTML.

  • effectDesc: A string describing the reward for having the milestone. You will have to implement the reward elsewhere. It can also be a function that returns updating text. Can use basic HTML.

  • done(): A function returning a boolean to determine if the milestone should be awarded.

  • toggles: optional, Creates toggle buttons that appear on the milestone when it is unlocked. The toggles can toggle a given boolean value in a layer. It is defined as an array of paired items, one pair per toggle. The first is the internal name of the layer the value being toggled is stored in, and the second is the internal name of the variable to toggle. (e.g. [["b", "auto"], ["g", "auto"])

         **Tip:** Toggles are not de-set if the milestone becomes locked! In this case, you should also check if the player has the milestone.
    -
  • style: Optional, Applies CSS to this milestone, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings)

  • unlocked(): Optional A function returning a boolean to determine if the milestone should be shown. If absent, it is always shown.

  • layer: Assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar

  • id: Assigned automagically. It's the "key" which the milestone was stored under, for convenient access. The milestone in the example's id is 0.

- +
  • style: Optional, Applies CSS to this milestone, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings)

  • unlocked(): Optional A function returning a boolean to determine if the milestone should be shown. If absent, it is always shown.

  • layer: Assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar

  • id: Assigned automagically. It's the "key" which the milestone was stored under, for convenient access. The milestone in the example's id is 0.

  • + \ No newline at end of file diff --git a/public/gamedevtree/docs/subtabs-and-microtabs.html b/public/gamedevtree/docs/subtabs-and-microtabs.html index 80f42c25f..58ba74105 100644 --- a/public/gamedevtree/docs/subtabs-and-microtabs.html +++ b/public/gamedevtree/docs/subtabs-and-microtabs.html @@ -6,12 +6,12 @@ Subtabs and Microtabs | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
    Skip to content

    Subtabs and Microtabs

    Subtabs are separate sections of a tab that you can view by selecting one at the top of the tab. Microtabs are smaller areas that function in much the same way.

    Subtabs are defined by using the tab format like this, where each element of tabFormat is given the name of that subtab:

    js
        tabFormat: {
    +    
    Skip to content

    Subtabs and Microtabs

    Subtabs are separate sections of a tab that you can view by selecting one at the top of the tab. Microtabs are smaller areas that function in much the same way.

    Subtabs are defined by using the tab format like this, where each element of tabFormat is given the name of that subtab:

    js
        tabFormat: {
             "Main tab": {
                 *subtab features*
             },
    @@ -72,8 +72,8 @@
             otherStuff: {
                 // There could be another set of microtabs here
             }
    -    },

    Normal subtabs and microtab subtabs both use the same features:

    Features:

    • content: The tab layout code for the subtab, in the tab layout format

    • style: Optional, Applies CSS to the whole subtab when switched to, in the form of an "CSS Object", where the keys are CSS attributes, and the values are the values for those attributes (both as strings)

    • buttonStyle: Optional, A CSS object, which affects the appearance of the button for that subtab.

    • unlocked(): Optional, a function to determine if the button for this subtab should be visible. By default, a subtab is always unlocked. (You can't use the "this" keyword in this function.)

    - + },

    Normal subtabs and microtab subtabs both use the same features:

    Features:

    • content: The tab layout code for the subtab, in the tab layout format

    • style: Optional, Applies CSS to the whole subtab when switched to, in the form of an "CSS Object", where the keys are CSS attributes, and the values are the values for those attributes (both as strings)

    • buttonStyle: Optional, A CSS object, which affects the appearance of the button for that subtab.

    • unlocked(): Optional, a function to determine if the button for this subtab should be visible. By default, a subtab is always unlocked. (You can't use the "this" keyword in this function.)

    + \ No newline at end of file diff --git a/public/gamedevtree/docs/updating-tmt.html b/public/gamedevtree/docs/updating-tmt.html index baade7a61..cd689f527 100644 --- a/public/gamedevtree/docs/updating-tmt.html +++ b/public/gamedevtree/docs/updating-tmt.html @@ -6,12 +6,12 @@ Updating The Modding Tree | The Paper Pilot - + - + - + @@ -50,8 +50,8 @@ -
    Skip to content

    Updating The Modding Tree

    This tutorial assumes that you have used the Getting Started Tutorial, and are using Github Desktop and VSCode for your mod.

    Here's what you have to do when there's a TMT update:

    1. Look at the changelog. It will warn you if the update will break anything or require any changes. Decide if you want to try to update.

    2. Open Github Desktop, and at the top middle, click "fetch origin". This will make Github Desktop get information about the update.

    3. Click where it says "current branch: master" at the top middle, and at the bottom of the thing that appears, click "choose a branch to merge into master.

    4. Select upstream/master. It will likely say there are conflicts, but you have tools to resolve them. Click "Merge upstream/master into master".

    5. A conflict happens when the things you're trying to merge have both made changes in the same place. Click "open in Visual Studio Code" next to the first file.

    6. Scroll down through the file, and look for the parts highlighted in red and green. One of these is your code, and the other is some code that will be modified by the update. Do your best to try to edit things to keep the updated changes, but keep your content.

    7. Continue to do this for all remaining challenges.

    8. Do any other changes required by the update, run the game, fix issues, etc.

    - +
    Skip to content

    Updating The Modding Tree

    This tutorial assumes that you have used the Getting Started Tutorial, and are using Github Desktop and VSCode for your mod.

    Here's what you have to do when there's a TMT update:

    1. Look at the changelog. It will warn you if the update will break anything or require any changes. Decide if you want to try to update.

    2. Open Github Desktop, and at the top middle, click "fetch origin". This will make Github Desktop get information about the update.

    3. Click where it says "current branch: master" at the top middle, and at the bottom of the thing that appears, click "choose a branch to merge into master.

    4. Select upstream/master. It will likely say there are conflicts, but you have tools to resolve them. Click "Merge upstream/master into master".

    5. A conflict happens when the things you're trying to merge have both made changes in the same place. Click "open in Visual Studio Code" next to the first file.

    6. Scroll down through the file, and look for the parts highlighted in red and green. One of these is your code, and the other is some code that will be modified by the update. Do your best to try to edit things to keep the updated changes, but keep your content.

    7. Continue to do this for all remaining challenges.

    8. Do any other changes required by the update, run the game, fix issues, etc.

    + \ No newline at end of file diff --git a/public/gamedevtree/docs/upgrades.html b/public/gamedevtree/docs/upgrades.html index 76bcd757c..21f190024 100644 --- a/public/gamedevtree/docs/upgrades.html +++ b/public/gamedevtree/docs/upgrades.html @@ -6,12 +6,12 @@ Upgrades | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
    Skip to content

    Upgrades

    Useful functions for dealing with Upgrades and implementing their effects:

    • hasUpgrade(layer, id): determine if the player has the upgrade
    • upgradeEffect(layer, id): Returns the current effects of the upgrade, if any
    • buyUpgrade(layer, id): Buys an upgrade directly (if affordable)

    Hint: Basic point gain is calculated in mod.js's "getPointGen".

    Upgrades are stored in the following format:

    js
        upgrades: {
    +    
    Skip to content

    Upgrades

    Useful functions for dealing with Upgrades and implementing their effects:

    • hasUpgrade(layer, id): determine if the player has the upgrade
    • upgradeEffect(layer, id): Returns the current effects of the upgrade, if any
    • buyUpgrade(layer, id): Buys an upgrade directly (if affordable)

    Hint: Basic point gain is calculated in mod.js's "getPointGen".

    Upgrades are stored in the following format:

    js
        upgrades: {
             rows: # of rows
             cols: # of columns
             11: {
    @@ -58,8 +58,8 @@
                 more features
             }
             etc
    -    }

    Each upgrade should have an id where the first digit is the row and the second digit is the column. Individual upgrades can have these features:

    • title: optional, displayed at the top in a larger font It can also be a function that returns updating text. Can use basic HTML.

    • description: A description of the upgrade's effect. You will also have to implement the effect where it is applied. It can also be a function that returns updating text. Can use basic HTML.

    • effect(): optional, A function that calculates and returns the current values of any bonuses from the upgrade. Can return a value or an object containing multiple values.

    • effectDisplay(): optional, A function that returns a display of the current effects of the upgrade with formatting. Default behavior is to just display the a number appropriately formatted. Can use basic HTML.

    • cost: A Decimal for the cost of the upgrade. By default, upgrades cost the main prestige currency for the layer.

    • unlocked(): optional, A function returning a bool to determine if the upgrade is visible or not. Default is unlocked.

    • onPurchase() - optional, this function will be called when the upgrade is purchased. Good for upgrades like "makes this layer act like it was unlocked first".

    By default, upgrades use the main prestige currency for the layer. You can include these to change them (but it needs to be a Decimal):

    • currencyDisplayName: optional, the name to display for the currency for the upgrade

    • currencyInternalName: optional, the internal name for that currency

    • currencyLayer: optional, the internal name of the layer that currency is stored in. If it's not in a layer (like Points), omit. If it's not stored directly in a layer, instead use the next feature.

    • currencyLocation: optional, if your currency is stored in something inside a layer (e.g. a buyable's amount), you can access it this way. This is a function returning the object in "player" that contains the value (like player[this.layer].buyables)

    • style: Optional, Applies CSS to this upgrade, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings)

    • layer: Assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar

    • id: Assigned automagically. It's the "key" which the upgrade was stored under, for convenient access. The upgrade in the example's id is 11.

    - + }

    Each upgrade should have an id where the first digit is the row and the second digit is the column. Individual upgrades can have these features:

    • title: optional, displayed at the top in a larger font It can also be a function that returns updating text. Can use basic HTML.

    • description: A description of the upgrade's effect. You will also have to implement the effect where it is applied. It can also be a function that returns updating text. Can use basic HTML.

    • effect(): optional, A function that calculates and returns the current values of any bonuses from the upgrade. Can return a value or an object containing multiple values.

    • effectDisplay(): optional, A function that returns a display of the current effects of the upgrade with formatting. Default behavior is to just display the a number appropriately formatted. Can use basic HTML.

    • cost: A Decimal for the cost of the upgrade. By default, upgrades cost the main prestige currency for the layer.

    • unlocked(): optional, A function returning a bool to determine if the upgrade is visible or not. Default is unlocked.

    • onPurchase() - optional, this function will be called when the upgrade is purchased. Good for upgrades like "makes this layer act like it was unlocked first".

    By default, upgrades use the main prestige currency for the layer. You can include these to change them (but it needs to be a Decimal):

    • currencyDisplayName: optional, the name to display for the currency for the upgrade

    • currencyInternalName: optional, the internal name for that currency

    • currencyLayer: optional, the internal name of the layer that currency is stored in. If it's not in a layer (like Points), omit. If it's not stored directly in a layer, instead use the next feature.

    • currencyLocation: optional, if your currency is stored in something inside a layer (e.g. a buyable's amount), you can access it this way. This is a function returning the object in "player" that contains the value (like player[this.layer].buyables)

    • style: Optional, Applies CSS to this upgrade, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings)

    • layer: Assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar

    • id: Assigned automagically. It's the "key" which the upgrade was stored under, for convenient access. The upgrade in the example's id is 11.

    + \ No newline at end of file diff --git a/public/kronos/Old Things/2.0-format-changes.html b/public/kronos/Old Things/2.0-format-changes.html index 2cb94eb00..f7c8e2ac4 100644 --- a/public/kronos/Old Things/2.0-format-changes.html +++ b/public/kronos/Old Things/2.0-format-changes.html @@ -6,12 +6,12 @@ 2.0 format changes | The Paper Pilot - + - + - + @@ -50,8 +50,8 @@ -
    Skip to content

    2.0 format changes

    • Temp format is changed from temp.something[layer] to temp[layer].something, for consistency
    • Challenges are now saved as an object with the amount of completions in each spot. (This will break saves.)
    • effectDisplay in Challenges and Upgrades no longer takes an argument, and neither does effect for Buyables
    • Buyable cost can take an argument for amount of buyables, but it needs to function if no argument is supplied (it should do the cost for the next purchase).
    • Generation of Points now happens in the main game loop (not in a layer update function), enabled by canGenPoints in game.js.
    • Changed fullLayerReset to layerDataReset, which takes an array of names of values to keep

    In addition, many names were changed, mostly expanding abbreviations:

    All instances of:

    • chall -> challenge
    • unl -> unlocked
    • upg -> upgrade (besides CSS)
    • amt -> amount
    • desc -> description
    • resCeil -> roundUpCost
    • order -> unlockOrder
    • incr_order -> increaseUnlockOrder

    Challenges:

    • desc -> challengeDescription
    • reward -> rewardDescription
    • effect -> rewardEffect
    • effectDisplay -> rewardDisplay
    • active -> challengeActive
    - +
    Skip to content

    2.0 format changes

    • Temp format is changed from temp.something[layer] to temp[layer].something, for consistency
    • Challenges are now saved as an object with the amount of completions in each spot. (This will break saves.)
    • effectDisplay in Challenges and Upgrades no longer takes an argument, and neither does effect for Buyables
    • Buyable cost can take an argument for amount of buyables, but it needs to function if no argument is supplied (it should do the cost for the next purchase).
    • Generation of Points now happens in the main game loop (not in a layer update function), enabled by canGenPoints in game.js.
    • Changed fullLayerReset to layerDataReset, which takes an array of names of values to keep

    In addition, many names were changed, mostly expanding abbreviations:

    All instances of:

    • chall -> challenge
    • unl -> unlocked
    • upg -> upgrade (besides CSS)
    • amt -> amount
    • desc -> description
    • resCeil -> roundUpCost
    • order -> unlockOrder
    • incr_order -> increaseUnlockOrder

    Challenges:

    • desc -> challengeDescription
    • reward -> rewardDescription
    • effect -> rewardEffect
    • effectDisplay -> rewardDisplay
    • active -> challengeActive
    + \ No newline at end of file diff --git a/public/kronos/README.html b/public/kronos/README.html index 7fbb60426..66d72a417 100644 --- a/public/kronos/README.html +++ b/public/kronos/README.html @@ -6,12 +6,12 @@ Kronos | The Paper Pilot - + - + - + @@ -50,8 +50,8 @@ -
    Skip to content

    Kronos

    Play here.

    Updating the website:

    • git submodule update --remote
    • git add -A
    • git commit -m "Updated kronos"
    • git push
    - +
    Skip to content

    Kronos

    Play here.

    Updating the website:

    • git submodule update --remote
    • git add -A
    • git commit -m "Updated kronos"
    • git push
    + \ No newline at end of file diff --git a/public/kronos/changelog.html b/public/kronos/changelog.html index cdb5e96da..cf3fc3f38 100644 --- a/public/kronos/changelog.html +++ b/public/kronos/changelog.html @@ -6,12 +6,12 @@ The Modding Tree changelog: | The Paper Pilot - + - + - + @@ -50,8 +50,8 @@ -
    Skip to content

    The Modding Tree changelog:

    v2.5.9.2 - 5/19/21

    • Fixed many issues with things not updating.

    v2.5.9.1 - 5/18/21

    • Made text inputs never give NaNs.

    v2.5.9 - 5/18/21

    • Fixed issue when using text inputs for Numbers.
    • Added particle color feature.
    • Particle speed and dir are updated as it moves.
    • Added setSpeed and setDir for particles.
    • Added more trig functions.

    v2.5.8 - 5/17/21

    • Added makeShinies, which creates a stationary particle in a random spot.
    • Bars will visually update more quickly.
    • Fixed a major particle-related issue.
    • Fixed autoUpgrade.
    • Fixed a minor visual issue with tree nodes.

    v2.5.7 - 5/15/21

    • Added a particle system! Not only can it be used for visual effects, but particles can interact with the mouse. They could be used to create golden cookies or collectables, for example.
    • Added marked feature to buyables, clickables, and challenges. By default, stars multi-completion challenges when maxed.
    • Added 'deactivated' feature to layers, which disables many features.
    • Improved number formatting slightly.

    v2.5.6 - 5/14/21

    • You can now use non-numeric ids for upgrades, buyables, etc.
    • Fixed an exploit that let you buy an extra buyable.
    • Moved basic getter/setter functions to easyAccess.js.

    v2.5.5.2 - 5/12/21

    • Fixed a major issue with buyables.
    • Fixed a variety of tabFormat-related issues.
    • Fixed commas appearing in decimal places (thanks to pg132!)

    v2.5.5.1 - 5/12/21

    • Fixed clickables.

    v2.5.5 - 5/12/21

    • Added grids! They are a grid of buttons which behave the same, but have their own data. Good for inventory grids, map tiles, and more!
    • Added "marked" feature to add a mark to a node. Can be an image instead of a star. (Originally by Jacorb)
    • Added "layer-proxy" component that lets you use components from another layer.
    • Added the ability to display non-whole numbers in main-display.

    v2.5.4 - 5/10/21

    • Added a setting to always use single-tab mode.
    • Added directMult, which multiplies prestige gain after exponents and softcaps. It actually multiplies gain for static layers.
    • Added onEnter and onExit for challenges.
    • Improved displaying numbers between 0.0001 and 0.1.
    • Added documentation on how gainMult/Exp work for static layers.
    • Fixed a visual issue on mobile, thanks to thepaperpilot.
    • Improved documentation in general.

    v2.5.3 - 5/8/21

    • Improved performance of tab formats and bars.
    • Respec confirmation settings are now kept on resets.
    • Improved compatibility with older browsers.
    • Fixed missing pixel on vertical bars.

    v2.5.2.1 - 5/7/21

    • Fixed microtabs making layers highlight incorrectly.

    v2.5.2 - 5/7/21

    • Added glowColor for subtabs.
    • Improved the display for extremely small numbers.
    • Fixed issues in the buyable docs.

    v2.5.1 - 5/7/21

    • Fixed dynamic things in tabFormat not updating.

    v2.5: Dreams Really Do Come True - 5/7/21

    • Optimizations, hopefully a significant amount.
    • Added OOM/s point gen display at high values (thanks to Ducdat!)
    • Only one tab will display if the window is not wide enough (also thanks to Ducdat!)
    • Holding down a buyable's button now buys it continuously.
    • New milestone setting will also show the most recently unlocked milestone. (Also renamed all settings to be clearer)
    • Added an onHold feature for clickables.
    • Layer nodes will be highlighted even if the player is on the same tab.
    • Added customizable node glowColor.
    • Added buyable purchaseLimit.
    • Amount is automatically supplied to buyable cost and effect functions.
    • Locked (not yet visible) milestones no longer take up space. Also fixed hidden milestones taking a tiny bit of space.
    • Re-centered respec buttons.
    • Force-displayed tooltips are not hidden by resets.
    • Added formatting support for very small numbers. Disabled in most places by default because rounding errors might cause issues. Access it with formatSmall, or enable it globally by adding "allowSmall: true" to modInfo.

    v2.4.1 - 4/29/21

    • A number of minor fixes, many thanks to thepaperpilot.
    • The respec confirmation checkbox is now part of the respec-button component. (This also fixes the checkbox appearing when there is no respec button)
    • Added a few undocumented changes to the 2.4 changelog (the two at the bottom)

    v2.4: Rationalized Edition - 4/29/21

    • Completely reworked tooltips. Shift-click a node to force its tooltip to stay displayed. (And hopefully finally fixed flickering!)

    • Added text-input and slider components.

    • Added the ability to toggle respec confirmations.

    • Added custom respec confirmation messages.

    • The red layer highlight will not appear before a layer is unlocked.

    • Added unlocking hotkeys.

    • You no longer need to supply 'rows' and 'cols' for any Big Features.

    • Node symbols can use HTML.

    • Added documentation for the respec button.

    • Added prestigeNotify to subtabs, and prestigeNotify in subtabs also highlights the layer node.

    • The version number no longer contains special characters or irrational numbers.

    • Added ctrlDown and shiftDown variables.

    • Tooltips now use HTML (this means you need to replace any newlines with
      )

    v2.π.1 - 4/7/21

    • Fixed formatting for some larger numbers.
    • Upgrades will expand if there is too much text to display.
    • Fixed styling challenges.
    • No longer attempts to display a base currency when there is none.

    v2.π: Incrementally Updated - 2/5/21

    • Performance improvements.
    • Fixed tooltips overlapping with the top display.
    • Clicking a popup dismisses it immediately.
    • Added support for bulk challenge completions.
    • "Best" is updated automatically.
    • Fixed keeping Decimal values on reset.
    • Code reorganization and style improvements by fudo.

    v2.3.5 - 12/21/20

    • Added resetTime, which tracks the time since a layer prestiged or was reset.
    • A layer node will be highlighted red if one of its subtabs is highlighted red.
    • Fixed issues with keeping challenges, buyables, and clickables on reset.
    • Improved the unlocking of custom layers.
    • Other minor fixes.

    v2.3.4 - 12/16/20

    • Added a node image feature.
    • Resource display now always shows the amount of the currency the layer's gain is based on.
    • Added spacing between tree nodes.
    • Another attempt to fix tooltip flickering.

    v2.3.3 - 12/13/20

    • Fixed the first node in a row always taking up space.
    • layerShown is now optional.
    • All prestige types can now use features for custom prestige types.

    v2.3.2 - 12/13/20

    • Fixed achievement/milestone popups.

    v2.3.1 - 12/12/20

    • Another attempt to fix flickering tooltips.
    • The "this" keyword should work everywhere except tabFormat arrays (although I may have missed some things).
    • Fixed tree branches not updating when scrolling on the right-side tab.
    • Fixed a spacing issue when a node's symbol is ""
    • Removed some old, unneeded files.

    v2.3: Cooler and Newer Edition - 12/10/20

    • Added achievement/milestone popups (thank you to Jacorb for this contribution!)
    • The changelog tab is back, and can be set in mod.js.
    • Layer nodes and respec buttons will not be clicked by pressing "enter".
    • Possible fix for flickering tooltips and strange transitions.
    • The victory screen text is configurable.
    • Added image and textStyle features to achievements.
    • Added an argument to use specific rows in an "upgrades" component.
    • Fixed the comma appearing in the main display when there was no effectDescription
    • Added the ability to easily make a tab that is a collection of layers in subtabs.
    • Improved spacing for embedding layers with subtabs into subtabs.

    v2.2.8 - 12/03/20

    • Double-clicking a layer node brings you to the main subtab for that layer.
    • Attempted to fix challenges visually updating a different way.
    • Added a softcap function for use in formulas.
    • Added displayRow feature, which lets layers be shown somewhere separate from where they are in the reset order (e.g. side layers)
    • Fixed autoupgrade issue.

    v2.2.7 - 11/30/20

    • Added autoUpgrade feature.
    • resource-display now shows resource gain per second if passiveGain is active.
    • Fixed formatting issues on some large numbers.
    • Better support for using classed objects in player and in layers/tmp.
    • Made hard resetting more effective.
    • Removed Herobrine from getStartClickables.

    v2.2.6 - 11/30/20

    • Added goalDescription for challenges and made the new "canComplete" system the standard.
    • Another attempt to fix challenges not visually updating.
    • Fixed side layers not appearing.
    • Fixed getStartClickables again.

    v2.2.5 - 11/29/20

    • Added features for overriding the displays and costs/goals of upgrades and challenges to make them fully custom.
    • best, total, and unlocked are always automatically added to layerData (but best and total will only display if you add them yourself).
    • Fixed getStartClickables.

    v2.2.4 - 11/28/20

    • Added softcap and softcapPower features (for Normal layers)
    • Offline time limit and default max tick length were fixed (previously the limits were 1000x too large)
    • Added fixOldSaves.
    • You can use HTML in main-display.
    • Fixed a number of minor oddities.

    v2.2.3 - 11/28/20

    • Layers will be highlighted if you can finish a challenge.
    • The "can complete challenge" color now overrides the "already completed" color.
    • Button nodes now work as side "layers".
    • Setting a tooltip to "" hides it entirely.

    v2.2.2 - 11/22/20

    • Fixed right half of the screen being unclickable in some circumstances.
    • Fixed tree branches being offset.
    • Fix to lastSafeTab.

    v2.2.1 - 11/7/20

    • Added a small highlight to layers you can meaningfully prestige on.
    • Added passiveGeneration and autoPrestige features to standardize prestige automation. (The old ways still work, but the new ones work better with other things)
    • Improved milestones visually a bit.
    • "best" and "total" are now only displayed if present in startData.
    • Fixed issues with things not updating visually. (Thank you to to Jacorb!)
    • Side layers and button nodes can now be highlighted.
    • Updated docs on the new tree-related features.

    v2.2: Uprooted - 11/7/20

    • You can now embed a layer inside of a subtab or microtab!
    • Added support for hiding or reformatting the tree tab
    • Added non-layer button nodes
    • Added shouldNotify to subtab/microtab buttons. (You can make them highlighted)
    • Added commas to large exponents.
    • Upgrades now only show "currently" if they have an effectDisplay (so not for constant effects).
    • Achievements are part of the default tab format.
    • NaN is now handled more intelligently.
    • Renamed files, and moved less relevant ones to another folder.
    • The "hide completed challenges" setting now only hides challenges at max completions.
    • Thank you to thepaperpilot for fixing errors in docs and improving the infobox appearance!
    • Many other minor fixes.

    v2.1.4 - 10/25/20

    • Added an infobox component. Thank you to thepaperpilot for this contribution!
    • Layer type is now optional, and defaults to "none".
    • Improved the look of bars and tab buttons.
    • Improved spacing between layer nodes (also thanks to thepaperpilot!)
    • Fixed the "blank" component breaking if only specifying the height.
    • Fixed some numbers not displaying with enough digits.
    • Made a few more things able to be functions.
    • A few other minor fixes.

    v2.1.3.1 - 10/21/20

    • Fixed the update function.

    v2.1.3 - 10/21/20

    • gainMult and gainExp are now optional.
    • Layer unlocking is now kept on reset.
    • Game should start up faster.
    • Layer updates now have a determined order and starts with earlier-rowed layers.
    • Automation now has a determined order and starts with later-rowed layers.
    • Fixed issues with resetting clickables and challenges.
    • Commas should no longer appear in the decimal places of a number.
    • Fixed potential issue in displaying the tree.

    v2.1.2 - 10/19/20

    • Added buyUpgrade function (buyUpg still works though)
    • Added author name to modInfo.
    • Fix to crash caused when the name of a subtab or microtab is changed.
    • Fixes to outdated information in docs.
    • Improvements to Discord links.
    • Thank you to thepaperpilot for contributing to this update!

    v2.1.1 - 10/17/20

    • Added resource-display component, which displays the base currency for the prestige layer, as well as the best and/or total of this layer's prestige currency.
    • Fixed the value for the base currency not updating in resource-display.

    v2.1: We should have thought of this sooner! - 10/17/20

    • Moved most of the code users will want to edit to mod.js, added documentation for it.
      • Specifically, modInfo, VERSION, canGenPoints, getPointGen, and maxTickLength
    • Added getStartPoints()
    • Added the ability to store non-layer-related data
    • Added the ability to display more things at the top of the tree tab below points.
    • Made the endgame condition customizable
    • Added "sell one" and "sell all" buttons for buyables.
    • Moved the old "game" to demo.js, and replaced it with a minimal game that won't cause issues when edited.
    • Fixed issues with version number
    • Fixed number formatting issue making things like "10e9" appear.

    v2.0.5 - 10/16/20

    • Made more features (including prestige parameters) able to be dynamic.
    • Layer nodes can be hidden but still take up space with "ghost" visibility
    • Added clickableEffect for real.
    • Fixed some visual issues with bars.
    • A few other minor tweaks and improvements.

    v2.0.4 - 10/16/20

    • Fixed HTML on buttons interfering with clicking on them.

    v2.0.3 - 10/16/20

    • Fixed hotkeys not displaying in info.
    • Fixed the game supressing all external hotkeys.
    • You can use more things as currencies for upgrade costs and challenge goals using currencyLocation.
    • Added maxTickLength, which can be used to prevent offline time or tab-switching from breaking time-limit based mechanics.
    • Made buyable respec buttons and clickable "master" buttons their own components, and gave them a hide/show feature.
    • Added a general "tooltip" feature for achievements.

    v2.0.2 - 10/15/20

    • Branches are now dynamic (they can be functions).
    • Fixed a crash related to offline time.
    • Fixed links being too wide.

    v2.0.1 - 10/15/20

    • Fixed side layers appearing multiple times.

    v2.0: The Pinnacle of Achievement Mountain - 10/15/20

    • Added progress bars, which are highly customizable and can be horizontal or vertical!
    • Added "side layers", displayed smaller and off to the side, and don't get reset by default. They can be used for global achievements and statistics. Speaking of which...
    • Added achievements!
    • Added clickables, a more generalized variant of buyables.
    • Almost every value in layer data can be either a function or a constant value!
    • Added support for multiple completions of challenges.
    • Added "none" prestige type, which removes the need for any other prestige-related features.
    • The points display and other gui elements stay at the top of the screen when the tree scrolls.
    • Added getter/setter functions for the amounts and effects of most Big Features
    • Moved modInfo to game.js, added a spot in modInfo for a Discord link, changelog link. Also added a separate mod version from the TMT version in VERSION.
    • Tree structure is based on layer data, no index.html editing is needed.
    • Tmp does not need to be manually updated.
    • You don't have to have the same amount of upgrades in every row (and challs and buyables)
    • "unlocked" is optional for all Big Components (defaults to true).
    • All displays will update correctly.
    • Changelog is no longer in index.html at all.
    • Generation of Points now happens in the main game loop
    • Changed the reset functions to make keeping things easier
    • Renamed many things to increase readability (see the list in the link below)
    • Improved documentation based on feedback

    v1.3.5:

    • Completely automated convertToDecimal, now you never have to worry about it again.
    • Branches can be defined without a color id. But they can also use hex values for color ids!
    • Created a tutorial for getting started with TMT and Github.
    • Page title is now automatically taken from mod name.

    v1.3.4 - 10/8/20

    • Added "midsection" feature to add things to a tab's layout while still keeping the standard layout.
    • Fix for being able to buy more buyables than you should.

    v1.3.3 - 10/7/20

    • Fix for the "order of operations" issue in temp.

    v1.3.1 - 10/7/20

    • Added custom CSS and tooltips for Layer Nodes.
    • Added custom CSS for upgrades, buyables, milestones, and challenges, both individually and layer-wide.
    • You can now use HTML in most display text!
    • You can now make milestones unlockable and not display immediately.
    • Fixed importing saves, and issue with upgrades not appearing, and probably more.
    • Optional "name" layer feature, used in confirmation messages.

    v1.3: Tabception... ception! - 10/7/20

    • Added subtabs! And also a Micro-tab component to let you make smaller subtab-esque areas anywhere.
    • Added a "custom" prestige formula type, and a number of features to support it.
    • Added points/sec display (can be disabled).
    • Added h-line, v-line and image-display components, plus components for individual upgrades, challenges, and milestones.
    • Added upgEffect, buyableEffect, and challEffect functions.
    • Added "hide completed challenges" setting.
    • Moved old changelogs to a separate place.
    • Fixed hasMilestone and incr_order.
    • Static layers now show the currency amount needed for the next one if you can buy max.

    v1.2.4 - 10/4/20

    • Layers are now highlighted if you can buy an upgrade, and a new feature, shouldNotify, lets you make it highlight other ways.
    • Fixed bugs with hasUpg, hasChall, hasMilestone, and inChallenge.
    • Changed the sample code to use the above functions for convenience.

    v1.2.3 - 10/3/20

    • Added a row component, which displays a list of objects in a row.
    • Added a column component, which displays a list of objects in a column (useful within a row).
    • Changed blanks to have a customizable width and height.

    v1.2: This Changes Everything! - 10/3/20

    • Many layer features can now be static values or functions. (This made some formats change, which will break old things)
    • You can now use the "this" keyword, to make code easier to transfer when making new layers.
    • Also added "this.layer", which is the current layer's name, and works on existing subfeatures (e.g. individual upgrades) as well! Subfeatures also have "this.id".
    • Fixed a big save issue. If you use a unique mod id, your save will never conflict with other mods.
    • Added a configurable offline time limit in modinfo at the top of index.html. (default 1 hour)
    • Added a few minor features, and updated the docs with new information.

    v1.1.1 - 9/30/20

    • You can define hotkeys directly from layer config.

    v1.1: Enhanced Edition - 9/30/20

    • Added "Buyables", which can function like Space Buildings or Enhancers.
    • Custom CSS can now be used on any component! Make the third argument an object with CSS parameters.
    • Lots of minor good things.

    v1.0 - 9/27/20

    • First release.
    - +
    Skip to content

    The Modding Tree changelog:

    v2.5.9.2 - 5/19/21

    • Fixed many issues with things not updating.

    v2.5.9.1 - 5/18/21

    • Made text inputs never give NaNs.

    v2.5.9 - 5/18/21

    • Fixed issue when using text inputs for Numbers.
    • Added particle color feature.
    • Particle speed and dir are updated as it moves.
    • Added setSpeed and setDir for particles.
    • Added more trig functions.

    v2.5.8 - 5/17/21

    • Added makeShinies, which creates a stationary particle in a random spot.
    • Bars will visually update more quickly.
    • Fixed a major particle-related issue.
    • Fixed autoUpgrade.
    • Fixed a minor visual issue with tree nodes.

    v2.5.7 - 5/15/21

    • Added a particle system! Not only can it be used for visual effects, but particles can interact with the mouse. They could be used to create golden cookies or collectables, for example.
    • Added marked feature to buyables, clickables, and challenges. By default, stars multi-completion challenges when maxed.
    • Added 'deactivated' feature to layers, which disables many features.
    • Improved number formatting slightly.

    v2.5.6 - 5/14/21

    • You can now use non-numeric ids for upgrades, buyables, etc.
    • Fixed an exploit that let you buy an extra buyable.
    • Moved basic getter/setter functions to easyAccess.js.

    v2.5.5.2 - 5/12/21

    • Fixed a major issue with buyables.
    • Fixed a variety of tabFormat-related issues.
    • Fixed commas appearing in decimal places (thanks to pg132!)

    v2.5.5.1 - 5/12/21

    • Fixed clickables.

    v2.5.5 - 5/12/21

    • Added grids! They are a grid of buttons which behave the same, but have their own data. Good for inventory grids, map tiles, and more!
    • Added "marked" feature to add a mark to a node. Can be an image instead of a star. (Originally by Jacorb)
    • Added "layer-proxy" component that lets you use components from another layer.
    • Added the ability to display non-whole numbers in main-display.

    v2.5.4 - 5/10/21

    • Added a setting to always use single-tab mode.
    • Added directMult, which multiplies prestige gain after exponents and softcaps. It actually multiplies gain for static layers.
    • Added onEnter and onExit for challenges.
    • Improved displaying numbers between 0.0001 and 0.1.
    • Added documentation on how gainMult/Exp work for static layers.
    • Fixed a visual issue on mobile, thanks to thepaperpilot.
    • Improved documentation in general.

    v2.5.3 - 5/8/21

    • Improved performance of tab formats and bars.
    • Respec confirmation settings are now kept on resets.
    • Improved compatibility with older browsers.
    • Fixed missing pixel on vertical bars.

    v2.5.2.1 - 5/7/21

    • Fixed microtabs making layers highlight incorrectly.

    v2.5.2 - 5/7/21

    • Added glowColor for subtabs.
    • Improved the display for extremely small numbers.
    • Fixed issues in the buyable docs.

    v2.5.1 - 5/7/21

    • Fixed dynamic things in tabFormat not updating.

    v2.5: Dreams Really Do Come True - 5/7/21

    • Optimizations, hopefully a significant amount.
    • Added OOM/s point gen display at high values (thanks to Ducdat!)
    • Only one tab will display if the window is not wide enough (also thanks to Ducdat!)
    • Holding down a buyable's button now buys it continuously.
    • New milestone setting will also show the most recently unlocked milestone. (Also renamed all settings to be clearer)
    • Added an onHold feature for clickables.
    • Layer nodes will be highlighted even if the player is on the same tab.
    • Added customizable node glowColor.
    • Added buyable purchaseLimit.
    • Amount is automatically supplied to buyable cost and effect functions.
    • Locked (not yet visible) milestones no longer take up space. Also fixed hidden milestones taking a tiny bit of space.
    • Re-centered respec buttons.
    • Force-displayed tooltips are not hidden by resets.
    • Added formatting support for very small numbers. Disabled in most places by default because rounding errors might cause issues. Access it with formatSmall, or enable it globally by adding "allowSmall: true" to modInfo.

    v2.4.1 - 4/29/21

    • A number of minor fixes, many thanks to thepaperpilot.
    • The respec confirmation checkbox is now part of the respec-button component. (This also fixes the checkbox appearing when there is no respec button)
    • Added a few undocumented changes to the 2.4 changelog (the two at the bottom)

    v2.4: Rationalized Edition - 4/29/21

    • Completely reworked tooltips. Shift-click a node to force its tooltip to stay displayed. (And hopefully finally fixed flickering!)

    • Added text-input and slider components.

    • Added the ability to toggle respec confirmations.

    • Added custom respec confirmation messages.

    • The red layer highlight will not appear before a layer is unlocked.

    • Added unlocking hotkeys.

    • You no longer need to supply 'rows' and 'cols' for any Big Features.

    • Node symbols can use HTML.

    • Added documentation for the respec button.

    • Added prestigeNotify to subtabs, and prestigeNotify in subtabs also highlights the layer node.

    • The version number no longer contains special characters or irrational numbers.

    • Added ctrlDown and shiftDown variables.

    • Tooltips now use HTML (this means you need to replace any newlines with
      )

    v2.π.1 - 4/7/21

    • Fixed formatting for some larger numbers.
    • Upgrades will expand if there is too much text to display.
    • Fixed styling challenges.
    • No longer attempts to display a base currency when there is none.

    v2.π: Incrementally Updated - 2/5/21

    • Performance improvements.
    • Fixed tooltips overlapping with the top display.
    • Clicking a popup dismisses it immediately.
    • Added support for bulk challenge completions.
    • "Best" is updated automatically.
    • Fixed keeping Decimal values on reset.
    • Code reorganization and style improvements by fudo.

    v2.3.5 - 12/21/20

    • Added resetTime, which tracks the time since a layer prestiged or was reset.
    • A layer node will be highlighted red if one of its subtabs is highlighted red.
    • Fixed issues with keeping challenges, buyables, and clickables on reset.
    • Improved the unlocking of custom layers.
    • Other minor fixes.

    v2.3.4 - 12/16/20

    • Added a node image feature.
    • Resource display now always shows the amount of the currency the layer's gain is based on.
    • Added spacing between tree nodes.
    • Another attempt to fix tooltip flickering.

    v2.3.3 - 12/13/20

    • Fixed the first node in a row always taking up space.
    • layerShown is now optional.
    • All prestige types can now use features for custom prestige types.

    v2.3.2 - 12/13/20

    • Fixed achievement/milestone popups.

    v2.3.1 - 12/12/20

    • Another attempt to fix flickering tooltips.
    • The "this" keyword should work everywhere except tabFormat arrays (although I may have missed some things).
    • Fixed tree branches not updating when scrolling on the right-side tab.
    • Fixed a spacing issue when a node's symbol is ""
    • Removed some old, unneeded files.

    v2.3: Cooler and Newer Edition - 12/10/20

    • Added achievement/milestone popups (thank you to Jacorb for this contribution!)
    • The changelog tab is back, and can be set in mod.js.
    • Layer nodes and respec buttons will not be clicked by pressing "enter".
    • Possible fix for flickering tooltips and strange transitions.
    • The victory screen text is configurable.
    • Added image and textStyle features to achievements.
    • Added an argument to use specific rows in an "upgrades" component.
    • Fixed the comma appearing in the main display when there was no effectDescription
    • Added the ability to easily make a tab that is a collection of layers in subtabs.
    • Improved spacing for embedding layers with subtabs into subtabs.

    v2.2.8 - 12/03/20

    • Double-clicking a layer node brings you to the main subtab for that layer.
    • Attempted to fix challenges visually updating a different way.
    • Added a softcap function for use in formulas.
    • Added displayRow feature, which lets layers be shown somewhere separate from where they are in the reset order (e.g. side layers)
    • Fixed autoupgrade issue.

    v2.2.7 - 11/30/20

    • Added autoUpgrade feature.
    • resource-display now shows resource gain per second if passiveGain is active.
    • Fixed formatting issues on some large numbers.
    • Better support for using classed objects in player and in layers/tmp.
    • Made hard resetting more effective.
    • Removed Herobrine from getStartClickables.

    v2.2.6 - 11/30/20

    • Added goalDescription for challenges and made the new "canComplete" system the standard.
    • Another attempt to fix challenges not visually updating.
    • Fixed side layers not appearing.
    • Fixed getStartClickables again.

    v2.2.5 - 11/29/20

    • Added features for overriding the displays and costs/goals of upgrades and challenges to make them fully custom.
    • best, total, and unlocked are always automatically added to layerData (but best and total will only display if you add them yourself).
    • Fixed getStartClickables.

    v2.2.4 - 11/28/20

    • Added softcap and softcapPower features (for Normal layers)
    • Offline time limit and default max tick length were fixed (previously the limits were 1000x too large)
    • Added fixOldSaves.
    • You can use HTML in main-display.
    • Fixed a number of minor oddities.

    v2.2.3 - 11/28/20

    • Layers will be highlighted if you can finish a challenge.
    • The "can complete challenge" color now overrides the "already completed" color.
    • Button nodes now work as side "layers".
    • Setting a tooltip to "" hides it entirely.

    v2.2.2 - 11/22/20

    • Fixed right half of the screen being unclickable in some circumstances.
    • Fixed tree branches being offset.
    • Fix to lastSafeTab.

    v2.2.1 - 11/7/20

    • Added a small highlight to layers you can meaningfully prestige on.
    • Added passiveGeneration and autoPrestige features to standardize prestige automation. (The old ways still work, but the new ones work better with other things)
    • Improved milestones visually a bit.
    • "best" and "total" are now only displayed if present in startData.
    • Fixed issues with things not updating visually. (Thank you to to Jacorb!)
    • Side layers and button nodes can now be highlighted.
    • Updated docs on the new tree-related features.

    v2.2: Uprooted - 11/7/20

    • You can now embed a layer inside of a subtab or microtab!
    • Added support for hiding or reformatting the tree tab
    • Added non-layer button nodes
    • Added shouldNotify to subtab/microtab buttons. (You can make them highlighted)
    • Added commas to large exponents.
    • Upgrades now only show "currently" if they have an effectDisplay (so not for constant effects).
    • Achievements are part of the default tab format.
    • NaN is now handled more intelligently.
    • Renamed files, and moved less relevant ones to another folder.
    • The "hide completed challenges" setting now only hides challenges at max completions.
    • Thank you to thepaperpilot for fixing errors in docs and improving the infobox appearance!
    • Many other minor fixes.

    v2.1.4 - 10/25/20

    • Added an infobox component. Thank you to thepaperpilot for this contribution!
    • Layer type is now optional, and defaults to "none".
    • Improved the look of bars and tab buttons.
    • Improved spacing between layer nodes (also thanks to thepaperpilot!)
    • Fixed the "blank" component breaking if only specifying the height.
    • Fixed some numbers not displaying with enough digits.
    • Made a few more things able to be functions.
    • A few other minor fixes.

    v2.1.3.1 - 10/21/20

    • Fixed the update function.

    v2.1.3 - 10/21/20

    • gainMult and gainExp are now optional.
    • Layer unlocking is now kept on reset.
    • Game should start up faster.
    • Layer updates now have a determined order and starts with earlier-rowed layers.
    • Automation now has a determined order and starts with later-rowed layers.
    • Fixed issues with resetting clickables and challenges.
    • Commas should no longer appear in the decimal places of a number.
    • Fixed potential issue in displaying the tree.

    v2.1.2 - 10/19/20

    • Added buyUpgrade function (buyUpg still works though)
    • Added author name to modInfo.
    • Fix to crash caused when the name of a subtab or microtab is changed.
    • Fixes to outdated information in docs.
    • Improvements to Discord links.
    • Thank you to thepaperpilot for contributing to this update!

    v2.1.1 - 10/17/20

    • Added resource-display component, which displays the base currency for the prestige layer, as well as the best and/or total of this layer's prestige currency.
    • Fixed the value for the base currency not updating in resource-display.

    v2.1: We should have thought of this sooner! - 10/17/20

    • Moved most of the code users will want to edit to mod.js, added documentation for it.
      • Specifically, modInfo, VERSION, canGenPoints, getPointGen, and maxTickLength
    • Added getStartPoints()
    • Added the ability to store non-layer-related data
    • Added the ability to display more things at the top of the tree tab below points.
    • Made the endgame condition customizable
    • Added "sell one" and "sell all" buttons for buyables.
    • Moved the old "game" to demo.js, and replaced it with a minimal game that won't cause issues when edited.
    • Fixed issues with version number
    • Fixed number formatting issue making things like "10e9" appear.

    v2.0.5 - 10/16/20

    • Made more features (including prestige parameters) able to be dynamic.
    • Layer nodes can be hidden but still take up space with "ghost" visibility
    • Added clickableEffect for real.
    • Fixed some visual issues with bars.
    • A few other minor tweaks and improvements.

    v2.0.4 - 10/16/20

    • Fixed HTML on buttons interfering with clicking on them.

    v2.0.3 - 10/16/20

    • Fixed hotkeys not displaying in info.
    • Fixed the game supressing all external hotkeys.
    • You can use more things as currencies for upgrade costs and challenge goals using currencyLocation.
    • Added maxTickLength, which can be used to prevent offline time or tab-switching from breaking time-limit based mechanics.
    • Made buyable respec buttons and clickable "master" buttons their own components, and gave them a hide/show feature.
    • Added a general "tooltip" feature for achievements.

    v2.0.2 - 10/15/20

    • Branches are now dynamic (they can be functions).
    • Fixed a crash related to offline time.
    • Fixed links being too wide.

    v2.0.1 - 10/15/20

    • Fixed side layers appearing multiple times.

    v2.0: The Pinnacle of Achievement Mountain - 10/15/20

    • Added progress bars, which are highly customizable and can be horizontal or vertical!
    • Added "side layers", displayed smaller and off to the side, and don't get reset by default. They can be used for global achievements and statistics. Speaking of which...
    • Added achievements!
    • Added clickables, a more generalized variant of buyables.
    • Almost every value in layer data can be either a function or a constant value!
    • Added support for multiple completions of challenges.
    • Added "none" prestige type, which removes the need for any other prestige-related features.
    • The points display and other gui elements stay at the top of the screen when the tree scrolls.
    • Added getter/setter functions for the amounts and effects of most Big Features
    • Moved modInfo to game.js, added a spot in modInfo for a Discord link, changelog link. Also added a separate mod version from the TMT version in VERSION.
    • Tree structure is based on layer data, no index.html editing is needed.
    • Tmp does not need to be manually updated.
    • You don't have to have the same amount of upgrades in every row (and challs and buyables)
    • "unlocked" is optional for all Big Components (defaults to true).
    • All displays will update correctly.
    • Changelog is no longer in index.html at all.
    • Generation of Points now happens in the main game loop
    • Changed the reset functions to make keeping things easier
    • Renamed many things to increase readability (see the list in the link below)
    • Improved documentation based on feedback

    v1.3.5:

    • Completely automated convertToDecimal, now you never have to worry about it again.
    • Branches can be defined without a color id. But they can also use hex values for color ids!
    • Created a tutorial for getting started with TMT and Github.
    • Page title is now automatically taken from mod name.

    v1.3.4 - 10/8/20

    • Added "midsection" feature to add things to a tab's layout while still keeping the standard layout.
    • Fix for being able to buy more buyables than you should.

    v1.3.3 - 10/7/20

    • Fix for the "order of operations" issue in temp.

    v1.3.1 - 10/7/20

    • Added custom CSS and tooltips for Layer Nodes.
    • Added custom CSS for upgrades, buyables, milestones, and challenges, both individually and layer-wide.
    • You can now use HTML in most display text!
    • You can now make milestones unlockable and not display immediately.
    • Fixed importing saves, and issue with upgrades not appearing, and probably more.
    • Optional "name" layer feature, used in confirmation messages.

    v1.3: Tabception... ception! - 10/7/20

    • Added subtabs! And also a Micro-tab component to let you make smaller subtab-esque areas anywhere.
    • Added a "custom" prestige formula type, and a number of features to support it.
    • Added points/sec display (can be disabled).
    • Added h-line, v-line and image-display components, plus components for individual upgrades, challenges, and milestones.
    • Added upgEffect, buyableEffect, and challEffect functions.
    • Added "hide completed challenges" setting.
    • Moved old changelogs to a separate place.
    • Fixed hasMilestone and incr_order.
    • Static layers now show the currency amount needed for the next one if you can buy max.

    v1.2.4 - 10/4/20

    • Layers are now highlighted if you can buy an upgrade, and a new feature, shouldNotify, lets you make it highlight other ways.
    • Fixed bugs with hasUpg, hasChall, hasMilestone, and inChallenge.
    • Changed the sample code to use the above functions for convenience.

    v1.2.3 - 10/3/20

    • Added a row component, which displays a list of objects in a row.
    • Added a column component, which displays a list of objects in a column (useful within a row).
    • Changed blanks to have a customizable width and height.

    v1.2: This Changes Everything! - 10/3/20

    • Many layer features can now be static values or functions. (This made some formats change, which will break old things)
    • You can now use the "this" keyword, to make code easier to transfer when making new layers.
    • Also added "this.layer", which is the current layer's name, and works on existing subfeatures (e.g. individual upgrades) as well! Subfeatures also have "this.id".
    • Fixed a big save issue. If you use a unique mod id, your save will never conflict with other mods.
    • Added a configurable offline time limit in modinfo at the top of index.html. (default 1 hour)
    • Added a few minor features, and updated the docs with new information.

    v1.1.1 - 9/30/20

    • You can define hotkeys directly from layer config.

    v1.1: Enhanced Edition - 9/30/20

    • Added "Buyables", which can function like Space Buildings or Enhancers.
    • Custom CSS can now be used on any component! Make the third argument an object with CSS parameters.
    • Lots of minor good things.

    v1.0 - 9/27/20

    • First release.
    + \ No newline at end of file diff --git a/public/kronos/docs/!general-info.html b/public/kronos/docs/!general-info.html index c5a631bba..0a334c222 100644 --- a/public/kronos/docs/!general-info.html +++ b/public/kronos/docs/!general-info.html @@ -6,12 +6,12 @@ The-Modding-Tree | The Paper Pilot - + - + - + @@ -50,8 +50,8 @@ -
    Skip to content

    The-Modding-Tree

    Making a game in The Modding Tree mostly involves defining parameters or functions on objects. If you aren't following the getting started guide, you should start by setting up your basic mod info in mod.js. It's important to set a mod id to ensure saving works properly.

    Beyond that, the main way to add content is through creating layers, often in layers.js. You can add new layers by calling addLayer(layername, layerdata). There is an example of a basic layer in layers.js showing the recommended method. It is just an example and can be freely deleted. You can also use it as a reference or a base for your own layers.

    Most of the time, you won't need to dive deep into the code to create things, but you still can if you really want to, for example to add new Vue components in components.js.

    The Modding Tree uses break_eternity.js to store large values. This means that many numbers are Decimal objects, and must be treated differently. For example, you have to use new Decimal(x) to create a Decimal value instead of a plain number, and perform operations on them by calling functions. e.g, instead of x = x + y, use x = x.add(y). Keep in mind this also applies to comparison operators, which should be replaced with calling the .gt, .gte, .lt, .lte, .eq, and .neq functions. See the break_eternity.js docs for more details on working with Decimal values.

    Almost all values can be either a constant value, or a dynamic value. Dynamic values are defined by putting a function that returns what the value should be at any given time.

    All display text can use basic HTML elements (But you can't use most Vue features there).

    While reading this documentation, the following key will be used when describing features:

    • No label: This is required and the game may crash if it isn't included.
    • sometimes required: This is may be required, depending on other things in the layer.
    • optional: You can leave this out if you don't intend to use that feature for the layer.
    • assigned automagically: This value will be set automatically and override any value you set.
    • deprecated: This feature is not recommended to be used, because newer features are able to achieve the same thing in a better, easier way.

    Table of Contents

    General

    • Getting Started: Getting your own copy of the code set up with Github Desktop.
    • Main mod info: How to set up general things for your mod in mod.js.
    • Basic layer breakdown: Breaking down the components of a layer with minimal features.
    • Layer features: Explanations of all of the different properties that you can give a layer.
    • Custom Tab Layouts: An optional way to give your tabs a different layout. You can even create entirely new components to use.
    • Custom game layouts: You can get rid of the tree tab, add buttons and other things to the tree, or even customize the tab's layout like a layer tab.
    • Updating TMT: Using Github Desktop to update your mod's version of TMT.

    Common components

    • Upgrades: How to create upgrades for a layer.
    • Milestones: How to create milestones for a layer.
    • Buyables: Create rebuyable upgrades for your layer (with the option to make them respec-able). Can be used to make Enhancers or Space Buildings, for example.
    • Clickables: A more generalized variant of buyables, for any kind of thing that is sometimes clickable. Between these and Buyables, you can do just about anything.
    • Achievements: How to create achievements for a layer (or for the whole game).

    Other components and features

    • Challenges: How to create challenges for a layer.
    • Bars: Display some information as a progress bar, gauge, or similar. They are highly customizable, and can be horizontal and vertical as well.
    • Subtabs and Microtabs: Create subtabs for your tabs, as well as "microtab" components that you can put inside the tabs. You can even use them to embed a layer inside another layer!
    • [Grids][grids.md]: Create a group buttons that behave the same, but have their own data. Good for map tiles, an inventory grid, and more!
    • Infoboxes: Boxes containing text that can be shown or hidden.
    • Trees: Make your own trees. You can make non-layer button nodes too!
    • Particle system: Can be used to create particles for visual effects, but also interactable things like golden cookies or collectables.
    - +
    Skip to content

    The-Modding-Tree

    Making a game in The Modding Tree mostly involves defining parameters or functions on objects. If you aren't following the getting started guide, you should start by setting up your basic mod info in mod.js. It's important to set a mod id to ensure saving works properly.

    Beyond that, the main way to add content is through creating layers, often in layers.js. You can add new layers by calling addLayer(layername, layerdata). There is an example of a basic layer in layers.js showing the recommended method. It is just an example and can be freely deleted. You can also use it as a reference or a base for your own layers.

    Most of the time, you won't need to dive deep into the code to create things, but you still can if you really want to, for example to add new Vue components in components.js.

    The Modding Tree uses break_eternity.js to store large values. This means that many numbers are Decimal objects, and must be treated differently. For example, you have to use new Decimal(x) to create a Decimal value instead of a plain number, and perform operations on them by calling functions. e.g, instead of x = x + y, use x = x.add(y). Keep in mind this also applies to comparison operators, which should be replaced with calling the .gt, .gte, .lt, .lte, .eq, and .neq functions. See the break_eternity.js docs for more details on working with Decimal values.

    Almost all values can be either a constant value, or a dynamic value. Dynamic values are defined by putting a function that returns what the value should be at any given time.

    All display text can use basic HTML elements (But you can't use most Vue features there).

    While reading this documentation, the following key will be used when describing features:

    • No label: This is required and the game may crash if it isn't included.
    • sometimes required: This is may be required, depending on other things in the layer.
    • optional: You can leave this out if you don't intend to use that feature for the layer.
    • assigned automagically: This value will be set automatically and override any value you set.
    • deprecated: This feature is not recommended to be used, because newer features are able to achieve the same thing in a better, easier way.

    Table of Contents

    General

    • Getting Started: Getting your own copy of the code set up with Github Desktop.
    • Main mod info: How to set up general things for your mod in mod.js.
    • Basic layer breakdown: Breaking down the components of a layer with minimal features.
    • Layer features: Explanations of all of the different properties that you can give a layer.
    • Custom Tab Layouts: An optional way to give your tabs a different layout. You can even create entirely new components to use.
    • Custom game layouts: You can get rid of the tree tab, add buttons and other things to the tree, or even customize the tab's layout like a layer tab.
    • Updating TMT: Using Github Desktop to update your mod's version of TMT.

    Common components

    • Upgrades: How to create upgrades for a layer.
    • Milestones: How to create milestones for a layer.
    • Buyables: Create rebuyable upgrades for your layer (with the option to make them respec-able). Can be used to make Enhancers or Space Buildings, for example.
    • Clickables: A more generalized variant of buyables, for any kind of thing that is sometimes clickable. Between these and Buyables, you can do just about anything.
    • Achievements: How to create achievements for a layer (or for the whole game).

    Other components and features

    • Challenges: How to create challenges for a layer.
    • Bars: Display some information as a progress bar, gauge, or similar. They are highly customizable, and can be horizontal and vertical as well.
    • Subtabs and Microtabs: Create subtabs for your tabs, as well as "microtab" components that you can put inside the tabs. You can even use them to embed a layer inside another layer!
    • [Grids][grids.md]: Create a group buttons that behave the same, but have their own data. Good for map tiles, an inventory grid, and more!
    • Infoboxes: Boxes containing text that can be shown or hidden.
    • Trees: Make your own trees. You can make non-layer button nodes too!
    • Particle system: Can be used to create particles for visual effects, but also interactable things like golden cookies or collectables.
    + \ No newline at end of file diff --git a/public/kronos/docs/achievements.html b/public/kronos/docs/achievements.html index f5c30de76..75c4988a7 100644 --- a/public/kronos/docs/achievements.html +++ b/public/kronos/docs/achievements.html @@ -6,12 +6,12 @@ Achievements | The Paper Pilot - + - + - + @@ -50,14 +50,14 @@ -
    Skip to content

    Achievements

    Achievements are awarded to the player when they meet a certain goal, and optionally give some benefit.

    You can make global achievements by putting them in a side layer by making its row equal to "side" instead of a number.

    Useful functions for dealing with achievements and implementing their effects:

    • hasAchievement(layer, id): determine if the player has the Achievement.
    • achievementEffect(layer, id): Returns the current effects of the achievement, if any.

    Achievements should be formatted like this:

    js
    achievements: {
    +    
    Skip to content

    Achievements

    Achievements are awarded to the player when they meet a certain goal, and optionally give some benefit.

    You can make global achievements by putting them in a side layer by making its row equal to "side" instead of a number.

    Useful functions for dealing with achievements and implementing their effects:

    • hasAchievement(layer, id): determine if the player has the Achievement.
    • achievementEffect(layer, id): Returns the current effects of the achievement, if any.

    Achievements should be formatted like this:

    js
    achievements: {
         11: {
             name: "Blah",
             more features
         },
         etc
    -}

    Usually, each achievement should have an id where the first digit is the row and the second digit is the column.

    Individual achievement can have these features:

    • name: optional. displayed at the top of the achievement. The only visible text. It can also be a function that returns updating text. Can use basic HTML.

    • done(): A function returning a boolean to determine if the achievement should be awarded.

    • tooltip: Default tooltip for the achievement, appears when it is hovered over. Should convey the goal and any reward for completing the achievement. It can also be a function that returns updating text. Can use basic HTML. Setting this to "" disables the tooltip.

    • effect(): optional. A function that calculates and returns the current values of any bonuses from the achievement. Can return a value or an object containing multiple values.

    • unlocked(): optional. A function returning a bool to determine if the achievement is visible or not. Default is unlocked.

    • onComplete() - optional. this function will be called when the achievement is completed.

    • image: optional, puts the image from the given URL (relative or absolute) in the achievement

    • style: optional. Applies CSS to this achievement, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • textStyle: optional. Applies CSS to the text, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the achievement was stored under, for convenient access. The achievement in the example's id is 11.

    • goalTooltip: optional, deprecated. Appears when the achievement is hovered over and locked, overrides the basic tooltip. This is to display the goal (or a hint). It can also be a function that returns updating text. Can use basic HTML.

    • doneTooltip: optional, deprecated. Appears when the achievement is hovered over and completed, overrides the basic tooltip. This can display what the player achieved (the goal), and the rewards, if any. It can also be a function that returns updating text. Can use basic HTML.

    Disable achievement popups by adding achievementsPopups: false to the layer.

    - +}

    Usually, each achievement should have an id where the first digit is the row and the second digit is the column.

    Individual achievement can have these features:

    • name: optional. displayed at the top of the achievement. The only visible text. It can also be a function that returns updating text. Can use basic HTML.

    • done(): A function returning a boolean to determine if the achievement should be awarded.

    • tooltip: Default tooltip for the achievement, appears when it is hovered over. Should convey the goal and any reward for completing the achievement. It can also be a function that returns updating text. Can use basic HTML. Setting this to "" disables the tooltip.

    • effect(): optional. A function that calculates and returns the current values of any bonuses from the achievement. Can return a value or an object containing multiple values.

    • unlocked(): optional. A function returning a bool to determine if the achievement is visible or not. Default is unlocked.

    • onComplete() - optional. this function will be called when the achievement is completed.

    • image: optional, puts the image from the given URL (relative or absolute) in the achievement

    • style: optional. Applies CSS to this achievement, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • textStyle: optional. Applies CSS to the text, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the achievement was stored under, for convenient access. The achievement in the example's id is 11.

    • goalTooltip: optional, deprecated. Appears when the achievement is hovered over and locked, overrides the basic tooltip. This is to display the goal (or a hint). It can also be a function that returns updating text. Can use basic HTML.

    • doneTooltip: optional, deprecated. Appears when the achievement is hovered over and completed, overrides the basic tooltip. This can display what the player achieved (the goal), and the rewards, if any. It can also be a function that returns updating text. Can use basic HTML.

    Disable achievement popups by adding achievementsPopups: false to the layer.

    + \ No newline at end of file diff --git a/public/kronos/docs/bars.html b/public/kronos/docs/bars.html index 27cb4e077..414cf4dc3 100644 --- a/public/kronos/docs/bars.html +++ b/public/kronos/docs/bars.html @@ -6,12 +6,12 @@ Bars | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
    Skip to content

    Bars

    Bars let you display information in a more direct way. It can be a progress bar, health bar, capacity gauge, or anything else.

    Bars are defined like other Big Features:

    js
    bars: {
    +    
    Skip to content

    Bars

    Bars let you display information in a more direct way. It can be a progress bar, health bar, capacity gauge, or anything else.

    Bars are defined like other Big Features:

    js
    bars: {
         bigBar: {
             direction: RIGHT,
             width: 200,
    @@ -59,8 +59,8 @@
             etc
         },
         etc
    -}

    Features:

    • direction: UP, DOWN, LEFT, or RIGHT (not strings). Determines the direction that the bar is filled as it progresses. RIGHT means from left to right.

    • width, height: The size in pixels of the bar, but as numbers (no "px" at the end).

    • progress(): A function that returns the portion of the bar that is filled, from "empty" at 0 to "full" at 1, updating automatically. (Nothing bad happens if the value goes out of these bounds, and it can be a number or Decimal)

    • display(): optional. A function that returns text to be displayed on top of the bar, can use HTML.

    • unlocked(): optional. A function returning a bool to determine if the bar is visible or not. Default is unlocked.

    • baseStyle, fillStyle, borderStyle, textStyle: Optional, Apply CSS to the unfilled portion, filled portion, border, and display text on the bar, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the bar was stored under, for convenient access. The bar in the example's id is "bigBar".

    - +}

    Features:

    • direction: UP, DOWN, LEFT, or RIGHT (not strings). Determines the direction that the bar is filled as it progresses. RIGHT means from left to right.

    • width, height: The size in pixels of the bar, but as numbers (no "px" at the end).

    • progress(): A function that returns the portion of the bar that is filled, from "empty" at 0 to "full" at 1, updating automatically. (Nothing bad happens if the value goes out of these bounds, and it can be a number or Decimal)

    • display(): optional. A function that returns text to be displayed on top of the bar, can use HTML.

    • unlocked(): optional. A function returning a bool to determine if the bar is visible or not. Default is unlocked.

    • baseStyle, fillStyle, borderStyle, textStyle: Optional, Apply CSS to the unfilled portion, filled portion, border, and display text on the bar, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the bar was stored under, for convenient access. The bar in the example's id is "bigBar".

    + \ No newline at end of file diff --git a/public/kronos/docs/basic-layer-breakdown.html b/public/kronos/docs/basic-layer-breakdown.html index fc0fc6dba..f010d79d6 100644 --- a/public/kronos/docs/basic-layer-breakdown.html +++ b/public/kronos/docs/basic-layer-breakdown.html @@ -6,12 +6,12 @@ Basic layer breakdown | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
    Skip to content

    Basic layer breakdown

    This is a very minimal layer with minimal features. Most things will require additional features.

    js
    addLayer("p", {
    +    
    Skip to content

    Basic layer breakdown

    This is a very minimal layer with minimal features. Most things will require additional features.

    js
    addLayer("p", {
         startData() { return {                  // startData is a function that returns default data for a layer. 
             unlocked: true,                     // You can add more variables here to add them to your layer.
             points: new Decimal(0),             // "points" is the internal name for the main resource of the layer.
    @@ -81,8 +81,8 @@
         upgrades: {
             // Look in the upgrades docs to see what goes here!
         },
    -})
    - +})
    + \ No newline at end of file diff --git a/public/kronos/docs/buyables.html b/public/kronos/docs/buyables.html index 58684241d..66a793154 100644 --- a/public/kronos/docs/buyables.html +++ b/public/kronos/docs/buyables.html @@ -6,12 +6,12 @@ Buyables | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
    Skip to content

    Buyables

    Buyables are usually things that can be bought multiple times with scaling costs. They come with optional buttons that can be used for respeccing or selling buyables, among other things.

    The amount of a buyable owned is a Decimal.

    Useful functions for dealing with buyables and implementing their effects:

    • getBuyableAmount(layer, id): get the amount of the buyable the player has
    • setBuyableAmount(layer, id, amount): set the amount of the buyable the player has
    • buyableEffect(layer, id): Returns the current effects of the buyable, if any.

    Buyables should be formatted like this:

    js
    buyables: {
    +    
    Skip to content

    Buyables

    Buyables are usually things that can be bought multiple times with scaling costs. They come with optional buttons that can be used for respeccing or selling buyables, among other things.

    The amount of a buyable owned is a Decimal.

    Useful functions for dealing with buyables and implementing their effects:

    • getBuyableAmount(layer, id): get the amount of the buyable the player has
    • setBuyableAmount(layer, id, amount): set the amount of the buyable the player has
    • buyableEffect(layer, id): Returns the current effects of the buyable, if any.

    Buyables should be formatted like this:

    js
    buyables: {
         11: {
             cost(x) { return new Decimal(1).mul(x) },
             display() { return "Blah" },
    @@ -62,8 +62,8 @@
             etc
         },
         etc
    -}

    Features:

    • title: optional. displayed at the top in a larger font. It can also be a function that returns updating text.

    • cost(): cost for buying the next buyable. Can have an optional argument "x" to calculate the cost of the x+1th purchase. (x is a Decimal). Can return an object if there are multiple currencies.

    • effect(): optional. A function that calculates and returns the current values of bonuses of this buyable. Can have an optional argument "x" to calculate the effect of having x of the buyable.. Can return a value or an object containing multiple values.

    • display(): A function returning everything that should be displayed on the buyable after the title, likely including the description, amount bought, cost, and current effect. Can use basic HTML.

    • unlocked(): optional. A function returning a bool to determine if the buyable is visible or not. Default is unlocked.

    • canAfford(): A function returning a bool to determine if you can buy one of the buyables.

    • buy(): A function that implements buying one of the buyable, including spending the currency.

    • buyMax(): optional. A function that implements buying as many of the buyable as possible.

    • style: optional. Applies CSS to this buyable, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • purchaseLimit: optional. The limit on how many of the buyable can be bought. The default is no limit.

    • marked: optional Adds a mark to the corner of the buyable. If it's "true" it will be a star, but it can also be an image URL.

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the buyable was stored under, for convenient access. The buyable in the example's id is 11.

    Sell One/Sell All:

    Including a sellOne or sellAll function will cause an additional button to appear beneath the buyable. They are functionally identical, but "sell one" appears above "sell all". You can also use them for other things.

    • sellOne/sellAll(): optional. Called when the button is pressed. The standard use would be to decrease/reset the amount of the buyable, and possibly return some currency to the player.

    • canSellOne/canSellAll(): optional. booleans determining whether or not to show the buttons. If "canSellOne/All" is absent but "sellOne/All" is present, the appropriate button will always show.

    To add a respec button, or something similar, add the respecBuyables function to the main buyables object (not individual buyables). You can use these features along with it:

    • respec(): optional. This is called when the button is pressed (after a toggleable confirmation message).

    • respecText: optional. Text to display on the respec Button.

    • showRespec(): optional. A function determining whether or not to show the button, if respecBuyables is defined. Defaults to true if absent.

    • respecMessage: optional. A custom confirmation message on respec, in place of the default one.

    - +}

    Features:

    • title: optional. displayed at the top in a larger font. It can also be a function that returns updating text.

    • cost(): cost for buying the next buyable. Can have an optional argument "x" to calculate the cost of the x+1th purchase. (x is a Decimal). Can return an object if there are multiple currencies.

    • effect(): optional. A function that calculates and returns the current values of bonuses of this buyable. Can have an optional argument "x" to calculate the effect of having x of the buyable.. Can return a value or an object containing multiple values.

    • display(): A function returning everything that should be displayed on the buyable after the title, likely including the description, amount bought, cost, and current effect. Can use basic HTML.

    • unlocked(): optional. A function returning a bool to determine if the buyable is visible or not. Default is unlocked.

    • canAfford(): A function returning a bool to determine if you can buy one of the buyables.

    • buy(): A function that implements buying one of the buyable, including spending the currency.

    • buyMax(): optional. A function that implements buying as many of the buyable as possible.

    • style: optional. Applies CSS to this buyable, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • purchaseLimit: optional. The limit on how many of the buyable can be bought. The default is no limit.

    • marked: optional Adds a mark to the corner of the buyable. If it's "true" it will be a star, but it can also be an image URL.

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the buyable was stored under, for convenient access. The buyable in the example's id is 11.

    Sell One/Sell All:

    Including a sellOne or sellAll function will cause an additional button to appear beneath the buyable. They are functionally identical, but "sell one" appears above "sell all". You can also use them for other things.

    • sellOne/sellAll(): optional. Called when the button is pressed. The standard use would be to decrease/reset the amount of the buyable, and possibly return some currency to the player.

    • canSellOne/canSellAll(): optional. booleans determining whether or not to show the buttons. If "canSellOne/All" is absent but "sellOne/All" is present, the appropriate button will always show.

    To add a respec button, or something similar, add the respecBuyables function to the main buyables object (not individual buyables). You can use these features along with it:

    • respec(): optional. This is called when the button is pressed (after a toggleable confirmation message).

    • respecText: optional. Text to display on the respec Button.

    • showRespec(): optional. A function determining whether or not to show the button, if respecBuyables is defined. Defaults to true if absent.

    • respecMessage: optional. A custom confirmation message on respec, in place of the default one.

    + \ No newline at end of file diff --git a/public/kronos/docs/challenges.html b/public/kronos/docs/challenges.html index 5f3b8f6f0..a61f18b52 100644 --- a/public/kronos/docs/challenges.html +++ b/public/kronos/docs/challenges.html @@ -6,12 +6,12 @@ Challenges | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
    Skip to content

    Challenges

    Challenges can have fully customizable win conditions. Useful functions for dealing with Challenges and implementing their effects:

    • inChallenge(layer, id): determine if the player is in a given challenge (or another challenge on the same layer that counts as this one).
    • hasChallenge(layer, id): determine if the player has completed the challenge.
    • challengeCompletions(layer, id): determine how many times the player completed the challenge.
    • maxedChallenge(layer, id): determines if the player has reached the maximum completions.
    • challengeEffect(layer, id): Returns the current effects of the challenge, if any.

    Challenges are stored in the following format:

    js
    challenges: {
    +    
    Skip to content

    Challenges

    Challenges can have fully customizable win conditions. Useful functions for dealing with Challenges and implementing their effects:

    • inChallenge(layer, id): determine if the player is in a given challenge (or another challenge on the same layer that counts as this one).
    • hasChallenge(layer, id): determine if the player has completed the challenge.
    • challengeCompletions(layer, id): determine how many times the player completed the challenge.
    • maxedChallenge(layer, id): determines if the player has reached the maximum completions.
    • challengeEffect(layer, id): Returns the current effects of the challenge, if any.

    Challenges are stored in the following format:

    js
    challenges: {
         11: {
             name: "Ouch",
             challengeDescription: "description of ouchie",
    @@ -58,8 +58,8 @@
             etc
         },
         etc
    -}

    Usually, each challenge should have an id where the first digit is the row and the second digit is the column.

    Individual Challenges can have these features:

    • name: Name of the challenge, can be a string or a function. Can use basic HTML.

    • challengeDescription: A description of what makes the challenge a challenge. You will need to implement these elsewhere. It can also be a function that returns updating text. Can use basic HTML.

    • goalDescription: A description of the win condition for the challenge. It can also be a function that returns updating text. Can use basic HTML. (Optional if using the old goal system)

    • canComplete(): A function that returns true if you meet the win condition for the challenge. Returning a number will allow bulk completing the challenge. (Optional if using the old goal system)

    • rewardDescription: A description of the reward's effect. You will also have to implement the effect where it is applied. It can also be a function that returns updating text. Can use basic HTML.

    • rewardEffect(): optional. A function that calculates and returns the current values of any bonuses from the reward. Can return a value or an object containing multiple values. Can use basic HTML.

    • rewardDisplay(): optional. A function that returns a display of the current effects of the reward with formatting. Default behavior is to just display the a number appropriately formatted.

    • fullDisplay(): OVERRIDE. Overrides the other displays and descriptions, and lets you set the full text for the challenge. Can use basic HTML.

    • unlocked(): optional. A function returning a bool to determine if the challenge is visible or not. Default is unlocked.

    • onComplete() - optional. this function will be called when the challenge is completed when previously incomplete.

    • onEnter() - optional. this function will be called when entering the challenge

    • onExit() - optional. this function will be called when exiting the challenge in any way

    • countsAs: optional. If a challenge combines the effects of other challenges in this layer, you can use this. An array of challenge ids. The player is effectively in all of those challenges when in the current one.

    • completionLimit: optional. the amount of times you can complete this challenge. Default is 1 completion.

    • style: optional. Applies CSS to this challenge, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • marked: optional Adds a mark to the corner of the challenge. If it's "true" it will be a star, but it can also be an image URL. By default, if the challenge has multiple completions, it will be starred at max completions.

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar

    • id: assigned automagically. It's the "key" which the challenge was stored under, for convenient access. The challenge in the example's id is 11.

    The old goal system uses these features:

    • goal: deprecated, A Decimal for the amount of currency required to beat the challenge. By default, the goal is in basic Points. The goal can also be a function if its value changes.

    • currencyDisplayName: deprecated. the name to display for the currency for the goal

    • currencyInternalName: deprecated. the internal name for that currency

    • currencyLayer: deprecated. the internal name of the layer that currency is stored in. If it's not in a layer, omit. If it's not stored directly in a layer, instead use the next feature.

    • currencyLocation(): deprecated. if your currency is stored in something inside a layer (e.g. a buyable's amount), you can access it this way. This is a function returning the object in "player" that contains the value (like player[this.layer].buyables)

    - +}

    Usually, each challenge should have an id where the first digit is the row and the second digit is the column.

    Individual Challenges can have these features:

    • name: Name of the challenge, can be a string or a function. Can use basic HTML.

    • challengeDescription: A description of what makes the challenge a challenge. You will need to implement these elsewhere. It can also be a function that returns updating text. Can use basic HTML.

    • goalDescription: A description of the win condition for the challenge. It can also be a function that returns updating text. Can use basic HTML. (Optional if using the old goal system)

    • canComplete(): A function that returns true if you meet the win condition for the challenge. Returning a number will allow bulk completing the challenge. (Optional if using the old goal system)

    • rewardDescription: A description of the reward's effect. You will also have to implement the effect where it is applied. It can also be a function that returns updating text. Can use basic HTML.

    • rewardEffect(): optional. A function that calculates and returns the current values of any bonuses from the reward. Can return a value or an object containing multiple values. Can use basic HTML.

    • rewardDisplay(): optional. A function that returns a display of the current effects of the reward with formatting. Default behavior is to just display the a number appropriately formatted.

    • fullDisplay(): OVERRIDE. Overrides the other displays and descriptions, and lets you set the full text for the challenge. Can use basic HTML.

    • unlocked(): optional. A function returning a bool to determine if the challenge is visible or not. Default is unlocked.

    • onComplete() - optional. this function will be called when the challenge is completed when previously incomplete.

    • onEnter() - optional. this function will be called when entering the challenge

    • onExit() - optional. this function will be called when exiting the challenge in any way

    • countsAs: optional. If a challenge combines the effects of other challenges in this layer, you can use this. An array of challenge ids. The player is effectively in all of those challenges when in the current one.

    • completionLimit: optional. the amount of times you can complete this challenge. Default is 1 completion.

    • style: optional. Applies CSS to this challenge, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • marked: optional Adds a mark to the corner of the challenge. If it's "true" it will be a star, but it can also be an image URL. By default, if the challenge has multiple completions, it will be starred at max completions.

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar

    • id: assigned automagically. It's the "key" which the challenge was stored under, for convenient access. The challenge in the example's id is 11.

    The old goal system uses these features:

    • goal: deprecated, A Decimal for the amount of currency required to beat the challenge. By default, the goal is in basic Points. The goal can also be a function if its value changes.

    • currencyDisplayName: deprecated. the name to display for the currency for the goal

    • currencyInternalName: deprecated. the internal name for that currency

    • currencyLayer: deprecated. the internal name of the layer that currency is stored in. If it's not in a layer, omit. If it's not stored directly in a layer, instead use the next feature.

    • currencyLocation(): deprecated. if your currency is stored in something inside a layer (e.g. a buyable's amount), you can access it this way. This is a function returning the object in "player" that contains the value (like player[this.layer].buyables)

    + \ No newline at end of file diff --git a/public/kronos/docs/clickables.html b/public/kronos/docs/clickables.html index e273f8696..c51754e78 100644 --- a/public/kronos/docs/clickables.html +++ b/public/kronos/docs/clickables.html @@ -6,12 +6,12 @@ Clickables | The Paper Pilot - + - + - + @@ -50,14 +50,14 @@ -
    Skip to content

    Clickables

    Clickables are any kind of thing that you can click for an effect. They're a more generalized version of Buyables.

    DO NOT USE THESE TO MAKE THINGS THAT YOU CLICK REPEATEDLY FOR A BONUS BECAUSE THOSE ARE AWFUL.

    There are several differences between the two. One is that a buyable's saved data is its amount as a Decimal, while Clickables store a "state" which can be a number or string, but not Decimal, array, or object). Buyables have a number of extra features which you can see on their page. Clickables also have a smaller default size.

    Useful functions for dealing with clickables and implementing their effects:

    • getClickableState(layer, id): get the state of the clickable the player has
    • setClickableState(layer, id, state): set the state of the clickable the player has
    • clickableEffect(layer, id): Returns the current effects of the clickable, if any.

    Clickables should be formatted like this:

    js
    clickables: {
    +    
    Skip to content

    Clickables

    Clickables are any kind of thing that you can click for an effect. They're a more generalized version of Buyables.

    DO NOT USE THESE TO MAKE THINGS THAT YOU CLICK REPEATEDLY FOR A BONUS BECAUSE THOSE ARE AWFUL.

    There are several differences between the two. One is that a buyable's saved data is its amount as a Decimal, while Clickables store a "state" which can be a number or string, but not Decimal, array, or object). Buyables have a number of extra features which you can see on their page. Clickables also have a smaller default size.

    Useful functions for dealing with clickables and implementing their effects:

    • getClickableState(layer, id): get the state of the clickable the player has
    • setClickableState(layer, id, state): set the state of the clickable the player has
    • clickableEffect(layer, id): Returns the current effects of the clickable, if any.

    Clickables should be formatted like this:

    js
    clickables: {
         11: {
             display() {return "Blah"},
             etc
         }
         etc
    -}

    Features:

    • title: optional. displayed at the top in a larger font. It can also be a function that returns updating text.

    • effect(): optional. A function that calculates and returns the current values of bonuses of this clickable. Can return a value or an object containing multiple values.

    • display(): A function returning everything that should be displayed on the clickable after the title, likely changing based on its state. Can use basic HTML.

    • unlocked(): optional. A function returning a bool to determine if the clickable is visible or not. Default is unlocked.

    • canClick(): A function returning a bool to determine if you can click the clickable.

    • onClick(): A function that implements clicking the clickable.

    • onHold(): optional A function that is called 20x/sec when the button is held for at least 0.25 seconds.

    • style: optional. Applies CSS to this clickable, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • marked: optional Adds a mark to the corner of the clickable. If it's "true" it will be a star, but it can also be an image URL.

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the clickable was stored under, for convenient access. The clickable in the example's id is 11.

    You can also use these features on the clickables object to add a button above all the clickables, for implementing a respec button or similar.

    • masterButtonPress(): optional. If present, an additional button will appear above the clickables. Pressing it will call this function.

    • masterButtonText: optional. Text to display on the Master Button.

    • showMasterButton(): optional. A function determining whether or not to show the button, if masterButtonPress is defined. Defaults to true if absent.

    - +}

    Features:

    • title: optional. displayed at the top in a larger font. It can also be a function that returns updating text.

    • effect(): optional. A function that calculates and returns the current values of bonuses of this clickable. Can return a value or an object containing multiple values.

    • display(): A function returning everything that should be displayed on the clickable after the title, likely changing based on its state. Can use basic HTML.

    • unlocked(): optional. A function returning a bool to determine if the clickable is visible or not. Default is unlocked.

    • canClick(): A function returning a bool to determine if you can click the clickable.

    • onClick(): A function that implements clicking the clickable.

    • onHold(): optional A function that is called 20x/sec when the button is held for at least 0.25 seconds.

    • style: optional. Applies CSS to this clickable, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • marked: optional Adds a mark to the corner of the clickable. If it's "true" it will be a star, but it can also be an image URL.

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the clickable was stored under, for convenient access. The clickable in the example's id is 11.

    You can also use these features on the clickables object to add a button above all the clickables, for implementing a respec button or similar.

    • masterButtonPress(): optional. If present, an additional button will appear above the clickables. Pressing it will call this function.

    • masterButtonText: optional. Text to display on the Master Button.

    • showMasterButton(): optional. A function determining whether or not to show the button, if masterButtonPress is defined. Defaults to true if absent.

    + \ No newline at end of file diff --git a/public/kronos/docs/custom-tab-layouts.html b/public/kronos/docs/custom-tab-layouts.html index eb21694b3..fe4c7bfba 100644 --- a/public/kronos/docs/custom-tab-layouts.html +++ b/public/kronos/docs/custom-tab-layouts.html @@ -6,12 +6,12 @@ Custom tab layouts | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
    Skip to content

    Custom tab layouts

    Note: If you are using subtabs, tabFormat is used differently, but the same format is used for defining their layouts. See here for more on subtabs.

    Custom tab layouts can be used to do basically anything in a tab window, especially combined with the "style" layer feature. The tabFormat feature is an array of things, like this:

    js
    tabFormat: [
    +    
    Skip to content

    Custom tab layouts

    Note: If you are using subtabs, tabFormat is used differently, but the same format is used for defining their layouts. See here for more on subtabs.

    Custom tab layouts can be used to do basically anything in a tab window, especially combined with the "style" layer feature. The tabFormat feature is an array of things, like this:

    js
    tabFormat: [
         "main-display",
         ["prestige-button", function() { return "Melt your points into " }],
         "blank",
    @@ -63,8 +63,8 @@
         "blank",
         "blank",
         "upgrades"
    -]

    It is a list of components, which can be either just a name, or an array with arguments. If it's an array, the first item is the name of the component, the second is the data passed into it, and the third (optional) applies a CSS style to it with a "CSS object", where the keys are CSS attributes.

    These are the existing components, but you can create more in components.js:

    • display-text: Displays some text (can use basic HTML). The argument is the text to display. It can also be a function that returns updating text.

    • raw-html: Displays some basic HTML, can also be a function.

    • blank: Adds empty space. The default dimensions are 8px x 17px. The argument changes the dimensions. If it's a single value (e.g. "20px"), that determines the height. If you have a pair of arguments, the first is width and the second is height.

    • row: Display a list of components horizontally. The argument is an array of components in the tab layout format.

    • column: Display a list of components vertically. The argument is an array of components in the tab layout format. This is useful to display columns within a row.

    • main-display: The text that displays the main currency for the layer and its effects. The argument is the amount of precision to use, allowing it to display non-whole numbers.

    • resource-display: The text that displays the currency that this layer is based on, as well as the best and/or total values for this layer's prestige currency (if they are put in startData for this layer).

    • prestige-button: The argument is a string that the prestige button should say before the amount of currency you will gain. It can also be a function that returns updating text.

    • text-input: A text input box. The argument is the name of the variable in player[layer] that the input is for, player[layer][argument] (Works with strings, numbers, and Decimals!)

    • slider: Lets the user input a value with a slider. The argument a 3-element array: [name, min, max]. The name is the name of the variable in player[layer] that the input that the input is for, and min and max are the limits of the slider. (Does not work for Decimal values)

    • upgrades: The layer's upgrades. The argument is optional, and is a the list of rows this component should include, if it doesn't have all of them.

    • milestones, challenges, achievements: Display the upgrades, milestones, and challenges for a layer, as appropriate.

    • buyables, clickables: Display all of the buyables/clickables for this layer, as appropriate. The argument is optional and is the size of the boxes in pixels.

    • microtabs: Display a set of subtabs for an area. The argument is the name of the set of microtabs in the "microtabs" feature.

    • bar: Display a bar. The argument is the id of the bar to display.

    • infobox: Display an infobox. The argument is the id of the infobox to display.

    • tree: Displays a tree. The argument is an array of arrays containing the names of the nodes in the tree (first by row, then by column) See here for more information on tree layouts and nodes!

    • toggle: A toggle button that toggles a bool value. The argument is a pair that identifies the location in player of the bool to toggle, e.g. [layer, id]. 'layer' also affects the color of the toggle.

    • grid: Displays the gridable grid for the layer. If you need more than one grid, use a layer proxy.

    • layer-proxy: Lets you use components from another layer. The argument is a pair, [layer, data], consisting of the id of the layer to proxy from, and the tabFormat for the components to show. (Note: you cannot use a microtab within a layer proxy)

    The rest of the components are sub-components. They can be used just like other components, but are typically part of another component.

    • upgrade, milestone, challenge, buyable, clickable, achievement, gridable: An individual upgrade, challenge, etc. The argument is the id. This can be used if you want to have upgrades split up across multiple subtabs, for example.

    • respec-button, master-button: The respec and master buttons for buyables and clickables, respectively.

    • sell-one, sell-all: The "sell one" and "sell all" for buyables, respectively. The argument is the id of the buyable.

    - +]

    It is a list of components, which can be either just a name, or an array with arguments. If it's an array, the first item is the name of the component, the second is the data passed into it, and the third (optional) applies a CSS style to it with a "CSS object", where the keys are CSS attributes.

    These are the existing components, but you can create more in components.js:

    • display-text: Displays some text (can use basic HTML). The argument is the text to display. It can also be a function that returns updating text.

    • raw-html: Displays some basic HTML, can also be a function.

    • blank: Adds empty space. The default dimensions are 8px x 17px. The argument changes the dimensions. If it's a single value (e.g. "20px"), that determines the height. If you have a pair of arguments, the first is width and the second is height.

    • row: Display a list of components horizontally. The argument is an array of components in the tab layout format.

    • column: Display a list of components vertically. The argument is an array of components in the tab layout format. This is useful to display columns within a row.

    • main-display: The text that displays the main currency for the layer and its effects. The argument is the amount of precision to use, allowing it to display non-whole numbers.

    • resource-display: The text that displays the currency that this layer is based on, as well as the best and/or total values for this layer's prestige currency (if they are put in startData for this layer).

    • prestige-button: The argument is a string that the prestige button should say before the amount of currency you will gain. It can also be a function that returns updating text.

    • text-input: A text input box. The argument is the name of the variable in player[layer] that the input is for, player[layer][argument] (Works with strings, numbers, and Decimals!)

    • slider: Lets the user input a value with a slider. The argument a 3-element array: [name, min, max]. The name is the name of the variable in player[layer] that the input that the input is for, and min and max are the limits of the slider. (Does not work for Decimal values)

    • upgrades: The layer's upgrades. The argument is optional, and is a the list of rows this component should include, if it doesn't have all of them.

    • milestones, challenges, achievements: Display the upgrades, milestones, and challenges for a layer, as appropriate.

    • buyables, clickables: Display all of the buyables/clickables for this layer, as appropriate. The argument is optional and is the size of the boxes in pixels.

    • microtabs: Display a set of subtabs for an area. The argument is the name of the set of microtabs in the "microtabs" feature.

    • bar: Display a bar. The argument is the id of the bar to display.

    • infobox: Display an infobox. The argument is the id of the infobox to display.

    • tree: Displays a tree. The argument is an array of arrays containing the names of the nodes in the tree (first by row, then by column) See here for more information on tree layouts and nodes!

    • toggle: A toggle button that toggles a bool value. The argument is a pair that identifies the location in player of the bool to toggle, e.g. [layer, id]. 'layer' also affects the color of the toggle.

    • grid: Displays the gridable grid for the layer. If you need more than one grid, use a layer proxy.

    • layer-proxy: Lets you use components from another layer. The argument is a pair, [layer, data], consisting of the id of the layer to proxy from, and the tabFormat for the components to show. (Note: you cannot use a microtab within a layer proxy)

    The rest of the components are sub-components. They can be used just like other components, but are typically part of another component.

    • upgrade, milestone, challenge, buyable, clickable, achievement, gridable: An individual upgrade, challenge, etc. The argument is the id. This can be used if you want to have upgrades split up across multiple subtabs, for example.

    • respec-button, master-button: The respec and master buttons for buyables and clickables, respectively.

    • sell-one, sell-all: The "sell one" and "sell all" for buyables, respectively. The argument is the id of the buyable.

    + \ No newline at end of file diff --git a/public/kronos/docs/getting-started.html b/public/kronos/docs/getting-started.html index 5d9b4bc24..4a974727d 100644 --- a/public/kronos/docs/getting-started.html +++ b/public/kronos/docs/getting-started.html @@ -6,12 +6,12 @@ Getting started | The Paper Pilot - + - + - + @@ -50,8 +50,8 @@ -
    Skip to content

    Getting started

    Welcome to The Modding Tree!

    Using the Modding Tree, at its simplest level, just requires getting a copy of it onto your computer. However, if you do it the right way, it will help in many ways.

    Don't let the word "Github" scare you away. It's actually much easier to use than most people think, especially because most people use it the hard way. The key is Github Desktop, which lets you do everything you need to, without even touching the command line.

    The benefits of using Github:

    • It makes it much, much easier to update The Modding Tree.
    • You can share your work without any extra effort using githack, or with a bit more effort, set up a github.io site.
    • It lets you undo changes to your code, and to have multiple versions of it.
    • It lets you collaborate with other people, if you want to.

    Getting set up with Github Desktop, Visual Studio Code, and The Modding Tree:

    1. Install Github Desktop and Visual Studio Code.

    2. Make a Github account. You can handle this on your own.

    3. Log in on your browser, and go back to The Modding Tree page. At the top right, there should be a button that says "fork". Click on it, and then on your username. You now have your own fork, or copy, of The Modding Tree.

    4. Open Github Desktop and log in. Ignore everything else and choose "clone a repository". A "repository" is basically a "Github project", like The Modding Tree. "Cloning" is downloading a copy of the repository to your computer.

    5. Look for The Modding Tree in the list of repositiories (it should be the only one) and click "clone".

    6. Select that you're using it for your own purposes, and click continue. It will download the files and handle everything.

    Using your repository

    1. Click on "show in explorer/finder" to the right, and then open the index.html file in the folder. The page should open up on your browser. This will let you view and test your project locally!

    2. To edit your project, click "open in VSCode" in Github Desktop.

    3. Open mod.js in VSCode, and look at the top part where it has a "modInfo" object. Fill in your mod's name to whatever you want, and change the id as well. (It can be any string value, and it's used to determine where the savefile is. Make it something that's probably unique, and don't change it again later or else it'll effectively wipe existing saves)

    4. Save mod.js, and then reload index.html in your browser. The title on the tab, as well as on the info page, will now be updated! You can reload the page every time you change the code to test it quickly and easily.

    5. Go back to Github Desktop. It's time to save your changes into the git system by making a "commit". This basically saves your work and creates a snapshot of what your code looks like at this moment, allowing you to look back at it later.

    6. At the bottom right corner, add a summary of your changes, and then click "commit to master".

    7. Finally, at the top middle, click "push origin" to push your changes out onto the online repository.

    8. You can view your project on line, or share it with others, by going to https://raw.githack.com/[YOUR-GITHUB-USERNAME]/The-Modding-Tree/master/index.html

    And now, you have successfully used Github! You can look at the documentation to see how The Modding Tree's system works and to make your mod a reality.

    - +
    Skip to content

    Getting started

    Welcome to The Modding Tree!

    Using the Modding Tree, at its simplest level, just requires getting a copy of it onto your computer. However, if you do it the right way, it will help in many ways.

    Don't let the word "Github" scare you away. It's actually much easier to use than most people think, especially because most people use it the hard way. The key is Github Desktop, which lets you do everything you need to, without even touching the command line.

    The benefits of using Github:

    • It makes it much, much easier to update The Modding Tree.
    • You can share your work without any extra effort using githack, or with a bit more effort, set up a github.io site.
    • It lets you undo changes to your code, and to have multiple versions of it.
    • It lets you collaborate with other people, if you want to.

    Getting set up with Github Desktop, Visual Studio Code, and The Modding Tree:

    1. Install Github Desktop and Visual Studio Code.

    2. Make a Github account. You can handle this on your own.

    3. Log in on your browser, and go back to The Modding Tree page. At the top right, there should be a button that says "fork". Click on it, and then on your username. You now have your own fork, or copy, of The Modding Tree.

    4. Open Github Desktop and log in. Ignore everything else and choose "clone a repository". A "repository" is basically a "Github project", like The Modding Tree. "Cloning" is downloading a copy of the repository to your computer.

    5. Look for The Modding Tree in the list of repositiories (it should be the only one) and click "clone".

    6. Select that you're using it for your own purposes, and click continue. It will download the files and handle everything.

    Using your repository

    1. Click on "show in explorer/finder" to the right, and then open the index.html file in the folder. The page should open up on your browser. This will let you view and test your project locally!

    2. To edit your project, click "open in VSCode" in Github Desktop.

    3. Open mod.js in VSCode, and look at the top part where it has a "modInfo" object. Fill in your mod's name to whatever you want, and change the id as well. (It can be any string value, and it's used to determine where the savefile is. Make it something that's probably unique, and don't change it again later or else it'll effectively wipe existing saves)

    4. Save mod.js, and then reload index.html in your browser. The title on the tab, as well as on the info page, will now be updated! You can reload the page every time you change the code to test it quickly and easily.

    5. Go back to Github Desktop. It's time to save your changes into the git system by making a "commit". This basically saves your work and creates a snapshot of what your code looks like at this moment, allowing you to look back at it later.

    6. At the bottom right corner, add a summary of your changes, and then click "commit to master".

    7. Finally, at the top middle, click "push origin" to push your changes out onto the online repository.

    8. You can view your project on line, or share it with others, by going to https://raw.githack.com/[YOUR-GITHUB-USERNAME]/The-Modding-Tree/master/index.html

    And now, you have successfully used Github! You can look at the documentation to see how The Modding Tree's system works and to make your mod a reality.

    + \ No newline at end of file diff --git a/public/kronos/docs/grids.html b/public/kronos/docs/grids.html index 327845f16..7b5b91c57 100644 --- a/public/kronos/docs/grids.html +++ b/public/kronos/docs/grids.html @@ -6,12 +6,12 @@ Grids | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
    Skip to content

    Grids

    Grids are an easier way of making a group of similar clickables. They all have the same behavior, but are different based on their data.

    NOTE: Gridables are similar to clickables in some respects, but are fundamentally different from normal TMT components in quite a few ways. Be sure to keep these in mind:

    • Gridable ids use base 100 instead of base 10, so you can have more than 10 tiles in a row. This means that a grid might look like this: 101 102 201 202
    • Individual gridables are not defined individually. All properties go directly into the "grid" object. Functions are called with arguments for the id of the gridables and its associated data, so you can give them the appropriate appearance and properties based on that.
    • If you need two unrelated grids in a layer, you'll need to use a layer proxy component.

    Useful functions for dealing with grids:

    • getGridData(layer, id): get the data for the chosen gridable
    • setGridData(layer, id, state): set the data for the chosen gridable
    • gridEffect(layer, id): get the effect for the chosen gridable

    The grid should be formatted like this:

    js
    grid: {
    +    
    Skip to content

    Grids

    Grids are an easier way of making a group of similar clickables. They all have the same behavior, but are different based on their data.

    NOTE: Gridables are similar to clickables in some respects, but are fundamentally different from normal TMT components in quite a few ways. Be sure to keep these in mind:

    • Gridable ids use base 100 instead of base 10, so you can have more than 10 tiles in a row. This means that a grid might look like this: 101 102 201 202
    • Individual gridables are not defined individually. All properties go directly into the "grid" object. Functions are called with arguments for the id of the gridables and its associated data, so you can give them the appropriate appearance and properties based on that.
    • If you need two unrelated grids in a layer, you'll need to use a layer proxy component.

    Useful functions for dealing with grids:

    • getGridData(layer, id): get the data for the chosen gridable
    • setGridData(layer, id, state): set the data for the chosen gridable
    • gridEffect(layer, id): get the effect for the chosen gridable

    The grid should be formatted like this:

    js
    grid: {
         rows: 4, // If these are dynamic make sure to have a max value as well!
         cols: 5,
         getStartData(id) {
    @@ -70,8 +70,8 @@
         },
     
         etc
    -}

    Features:

    • rows, cols: The amount of rows and columns of gridable to display.

    • maxRows, maxCols: sometimes needed. If rows or cols are dynamic, you need to define the maximum amount that there can be (you can increase it when you update the game though). These CANNOT be dynamic.

    • getStartData(id): Creates the default data for the gridable at this position. This can be an object, or a regular value.

    • getUnlocked(id): optional. Returns true if the gridable at this position should be visible.

    • getTitle(data, id): optional. Returns text that should displayed at the top in a larger font, based on the position and data of the gridable.

    • getDisplay(data, id): optional. Returns everything that should be displayed on the gridable after the title, based on the position and data of the gridable.

    • getStyle(data, id): optional. Returns CSS to apply to this gridable, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • getCanClick(data, id): optional. A function returning a bool to determine if you can click a gridable, based on its data and position. If absent, you can always click it.

    • onClick(data, id): A function that implements clicking on the gridable, based on its position and data.

    • onHold(data, id): optional A function that is called 20x/sec when the button is held for at least 0.25 seconds.

    • getEffect(data, id): optional. A function that calculates and returns a gridable's effect, based on its position and data. (Whatever that means for a gridable)

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    - +}

    Features:

    • rows, cols: The amount of rows and columns of gridable to display.

    • maxRows, maxCols: sometimes needed. If rows or cols are dynamic, you need to define the maximum amount that there can be (you can increase it when you update the game though). These CANNOT be dynamic.

    • getStartData(id): Creates the default data for the gridable at this position. This can be an object, or a regular value.

    • getUnlocked(id): optional. Returns true if the gridable at this position should be visible.

    • getTitle(data, id): optional. Returns text that should displayed at the top in a larger font, based on the position and data of the gridable.

    • getDisplay(data, id): optional. Returns everything that should be displayed on the gridable after the title, based on the position and data of the gridable.

    • getStyle(data, id): optional. Returns CSS to apply to this gridable, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • getCanClick(data, id): optional. A function returning a bool to determine if you can click a gridable, based on its data and position. If absent, you can always click it.

    • onClick(data, id): A function that implements clicking on the gridable, based on its position and data.

    • onHold(data, id): optional A function that is called 20x/sec when the button is held for at least 0.25 seconds.

    • getEffect(data, id): optional. A function that calculates and returns a gridable's effect, based on its position and data. (Whatever that means for a gridable)

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    + \ No newline at end of file diff --git a/public/kronos/docs/infoboxes.html b/public/kronos/docs/infoboxes.html index 6cd0feb51..df6df19f6 100644 --- a/public/kronos/docs/infoboxes.html +++ b/public/kronos/docs/infoboxes.html @@ -6,12 +6,12 @@ Infoboxes | The Paper Pilot - + - + - + @@ -50,15 +50,15 @@ -
    Skip to content

    Infoboxes

    Infoboxes are good for displaying "lore", or story elements, as well as for explaining complicated things.

    In the default tab layout, the first infobox will be displayed at the very top of the tab.

    Infoboxes are defined like other Big Features:

    js
    infoboxes: {
    +    
    Skip to content

    Infoboxes

    Infoboxes are good for displaying "lore", or story elements, as well as for explaining complicated things.

    In the default tab layout, the first infobox will be displayed at the very top of the tab.

    Infoboxes are defined like other Big Features:

    js
    infoboxes: {
         lore: {
             title: "foo",
             body() { return "bar" },
             etc
         },
         etc
    -}

    Features:

    • title: The text displayed above the main box. Can be a function to be dynamic, and can use basic HTML.

    • body: The text displayed inside the box. Can be a function to be dynamic, and can use basic HTML.

    • style, titleStyle, bodyStyle: optional. Apply CSS to the infobox, or to the title button or body of the infobox, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • unlocked(): optional. A function returning a bool to determine if the infobox is visible or not. Default is unlocked.

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar

    • id: assigned automagically. It's the "key" which the bar was stored under, for convenient access. The infobox in the example's id is "lore".

    - +}

    Features:

    • title: The text displayed above the main box. Can be a function to be dynamic, and can use basic HTML.

    • body: The text displayed inside the box. Can be a function to be dynamic, and can use basic HTML.

    • style, titleStyle, bodyStyle: optional. Apply CSS to the infobox, or to the title button or body of the infobox, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • unlocked(): optional. A function returning a bool to determine if the infobox is visible or not. Default is unlocked.

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar

    • id: assigned automagically. It's the "key" which the bar was stored under, for convenient access. The infobox in the example's id is "lore".

    + \ No newline at end of file diff --git a/public/kronos/docs/layer-features.html b/public/kronos/docs/layer-features.html index eb0a8bcbf..7eb3195cb 100644 --- a/public/kronos/docs/layer-features.html +++ b/public/kronos/docs/layer-features.html @@ -6,12 +6,12 @@ Layer Features | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
    Skip to content

    Layer Features

    This is a more comprehensive list of established features to add to layers. You can add more freely, if you want to have other functions or values associated with your layer. These have special functionality, though.

    You can make almost any value dynamic by using a function in its place, including all display strings and styling/color features.

    Layer Definition features

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar to access the saved value. It makes copying code to new layers easier. It is also assigned to all upgrades and buyables and such.

    • name: optional. used in reset confirmations (and the default infobox title). If absent, it just uses the layer's id.

    • startData(): A function to return the default save data for this layer. Add any variables you have to it. Make sure to use Decimal values rather than normal numbers.

      Standard values: - Required: - unlocked: a bool determining if this layer is unlocked or not - points: a Decimal, the main currency for the layer - Optional: - total: A Decimal, tracks total amount of main prestige currency. Always tracked, but only shown if you add it here. - best: A Decimal, tracks highest amount of main prestige currency. Always tracked, but only shown if you add it here. - unlockOrder: used to keep track of relevant layers unlocked before this one. - resetTime: A number, time since this layer was last prestiged (or reset by another layer)

    • color: A color associated with this layer, used in many places. (A string in hex format with a #)

    • row: The row of the layer, starting at 0. This affects where the node appears on the standard tree, and which resets affect the layer.

      Using "side" instead of a number will cause the layer to appear off to the side as a smaller node (useful for achievements and statistics). Side layers are not affected by resets unless you add a doReset to them.

    • displayRow: OVERRIDE Changes where the layer node appears without changing where it is in the reset order.

    • resource: Name of the main currency you gain by resetting on this layer.

    • effect(): optional. A function that calculates and returns the current values of any bonuses inherent to the main currency. Can return a value or an object containing multiple values. You will also have to implement the effect where it is applied.

    • effectDescription: optional. A function that returns a description of this effect. If the text stays constant, it can just be a string.

    • layerShown(): optional, A function returning a bool which determines if this layer's node should be visible on the tree. It can also return "ghost", which will hide the layer, but its node will still take up space in the tree. Defaults to true.

    • hotkeys: optional. An array containing information on any hotkeys associated with this layer:

      js
      hotkeys: [
      +    
      Skip to content

      Layer Features

      This is a more comprehensive list of established features to add to layers. You can add more freely, if you want to have other functions or values associated with your layer. These have special functionality, though.

      You can make almost any value dynamic by using a function in its place, including all display strings and styling/color features.

      Layer Definition features

      • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar to access the saved value. It makes copying code to new layers easier. It is also assigned to all upgrades and buyables and such.

      • name: optional. used in reset confirmations (and the default infobox title). If absent, it just uses the layer's id.

      • startData(): A function to return the default save data for this layer. Add any variables you have to it. Make sure to use Decimal values rather than normal numbers.

        Standard values: - Required: - unlocked: a bool determining if this layer is unlocked or not - points: a Decimal, the main currency for the layer - Optional: - total: A Decimal, tracks total amount of main prestige currency. Always tracked, but only shown if you add it here. - best: A Decimal, tracks highest amount of main prestige currency. Always tracked, but only shown if you add it here. - unlockOrder: used to keep track of relevant layers unlocked before this one. - resetTime: A number, time since this layer was last prestiged (or reset by another layer)

      • color: A color associated with this layer, used in many places. (A string in hex format with a #)

      • row: The row of the layer, starting at 0. This affects where the node appears on the standard tree, and which resets affect the layer.

        Using "side" instead of a number will cause the layer to appear off to the side as a smaller node (useful for achievements and statistics). Side layers are not affected by resets unless you add a doReset to them.

      • displayRow: OVERRIDE Changes where the layer node appears without changing where it is in the reset order.

      • resource: Name of the main currency you gain by resetting on this layer.

      • effect(): optional. A function that calculates and returns the current values of any bonuses inherent to the main currency. Can return a value or an object containing multiple values. You will also have to implement the effect where it is applied.

      • effectDescription: optional. A function that returns a description of this effect. If the text stays constant, it can just be a string.

      • layerShown(): optional, A function returning a bool which determines if this layer's node should be visible on the tree. It can also return "ghost", which will hide the layer, but its node will still take up space in the tree. Defaults to true.

      • hotkeys: optional. An array containing information on any hotkeys associated with this layer:

        js
        hotkeys: [
             {
                 key: "p", // What the hotkey button is. Use uppercase if it's combined with shift, or "ctrl+x" for holding down ctrl.
                 description: "p: reset your points for prestige points", // The description of the hotkey that is displayed in the game's How To Play tab
        @@ -60,8 +60,8 @@
         ]
      • style: optional. a "CSS object" where the keys are CSS attributes, containing any CSS that should affect this layer's entire tab.

      • tabFormat: optional. use this if you want to add extra things to your tab or change the layout. See here for more info.

      • midsection: optional, an alternative to tabFormat, which is inserted in between Milestones and Buyables in the standard tab layout. (cannot do subtabs)

      Big features (all optional)

      • upgrades: A set of one-time purchases which can have unique upgrade conditions, currency costs, and bonuses. See here for more info.

      • milestones: A list of bonuses gained upon reaching certain thresholds of a resource. Often used for automation/QOL. See here for more info.

      • challenges: The player can enter challenges, which make the game harder. If they reach a goal and beat the challenge, they recieve a bonus. See here for more info.

      • buyables: Effectively upgrades that can be bought multiple times, and are optionally respeccable. Many uses. See here for more info.

      • clickables: Extremely versatile and generalized buttons which can only be clicked sometimes. See here for more info.

      • microtabs: An area that functions like a set of subtabs, with buttons at the top changing the content within. (Advanced) See here for more info.

      • bars: Display some information as a progress bar, gague, or similar. They are highly customizable, and can be vertical as well. See here for more info.

      • achievements: Kind of like milestones, but with a different display style and some other differences. Extra features are on the way at a later date! See here for more info.

      • achievementPopups, milestonePopups: optional, If false, disables popup message when you get the achievement/milestone. True by default.

      • infoboxes: Displays some text in a box that can be shown or hidden. See here for more info.

      • grid: A grid of buttons that behave the same, but have their own data.See here for more info.

      Prestige formula features

      • type: optional. Determines which prestige formula you use. Defaults to "none".

        • "normal": The amount of currency you gain is independent of its current amount (like Prestige). The formula before bonuses is based on baseResource^exponent
        • "static": The cost is dependent on your total after reset. The formula before bonuses is based on base^(x^exponent)
        • "custom": You can define everything, from the calculations to the text on the button, yourself. (See more at the bottom)
        • "none": This layer does not prestige, and therefore does not need any of the other features in this section.
      • baseResource: The name of the resource that determines how much of the main currency you gain on reset.

      • baseAmount(): A function that gets the current value of the base resource.

      • requires: A Decimal, the amount of the base needed to gain 1 of the prestige currency. Also the amount required to unlock the layer. You can instead make this a function, to make it harder if another layer was unlocked first (based on unlockOrder).

      • exponent: Used as described above.

      • base: sometimes required. required for "static" layers, used as described above. If absent, defaults to 2. Must be greater than 1.

      • roundUpCost: optional. a bool, which is true if the resource cost needs to be rounded up. (use if the base resource is a "static" currency.)

      • gainMult(), gainExp(): optional. For normal layers, these functions calculate the multiplier and exponent on resource gain from upgrades and boosts and such. Plug in most bonuses here. For static layers, they instead divide and root the cost of the resource.

      • directMult(): optional. Directly multiplies the resource gain, after exponents and softcaps. For static layers, actually multiplies resource gain instead of reducing the cost.

      • softcap, softcapPower: optional. For normal layers, gain beyond [softcap] points is put to the [softcapPower]th power Default for softcap is e1e7, and for power is 0.5.

      • canBuyMax(): sometimes required. required for static layers, function used to determine if buying max is permitted.

      • onPrestige(gain): optional. A function that triggers when this layer prestiges, just before you gain the currency. Can be used to have secondary resource gain on prestige, or to recalculate things or whatnot.

      • resetDescription: optional. Use this to replace "Reset for " on the Prestige button with something else.

      • prestigeButtonText(): sometimes required. Use this to make the entirety of the text a Prestige button contains. Only required for custom layers, but usable by all types.

      • passiveGeneration(): optional, returns a regular number. You automatically generate your gain times this number every second (does nothing if absent) This is good for automating Normal layers.

      • autoPrestige(): optional, returns a boolean, if true, the layer will always automatically do a prestige if it can. This is good for automating Static layers.

      Tree/node features

      • symbol: optional. The text that appears on this layer's node. Default is the layer id with the first letter capitalized.

      • image: override. The url (local or global) of an image that goes on the node. (Overrides symbol)

      • position: optional. Determines the horizontal position of the layer in its row in a standard tree. By default, it uses the layer id, and layers are sorted in alphabetical order.

      • branches: optional. An array of layer/node ids. On a tree, a line will appear from this layer to all of the layers in the list. Alternatively, an entry in the array can be a 2-element array consisting of the layer id and a color value. The color value can either be a string with a hex color code, or a number from 1-3 (theme-affected colors).

      • nodeStyle: optional. A CSS object, where the keys are CSS attributes, which styles this layer's node on the tree.

      • tooltip() / tooltipLocked(): optional. Functions that return text, which is the tooltip for the node when the layer is unlocked or locked, respectively. By default the tooltips behave the same as in the original Prestige Tree. If the value is "", the tooltip will be disabled.

      • marked: optional Adds a mark to the corner of the node. If it's "true" it will be a star, but it can also be an image URL.

      Other features

      • doReset(resettingLayer): optional. Is triggered when a layer on a row greater than or equal to this one does a reset. The default behavior is to reset everything on the row, but only if it was triggered by a layer in a higher row. doReset is always called for side layers, but for these the default behavior is to reset nothing.

        If you want to keep things, determine what to keep based on resettingLayer, milestones, and such, then call layerDataReset(layer, keep), where layer is this layer, and keep is an array of the names of things to keep. It can include things like "points", "best", "total" (for this layer's prestige currency), "upgrades", any unique variables like "generatorPower", etc. If you want to only keep specific upgrades or something like that, save them in a separate variable, then call layerDataReset, and then set player[this.layer].upgrades to the saved upgrades.

      • update(diff): optional. This function is called every game tick. Use it for any passive resource production or time-based things. diff is the time since the last tick.

      • autoUpgrade: optional, a boolean value, if true, the game will attempt to buy this layer's upgrades every tick. Defaults to false.

      • automate(): optional. This function is called every game tick, after production. Use it to activate automation things that aren't otherwise supported.

      • resetsNothing: optional. Returns true if this layer shouldn't trigger any resets when you prestige.

      • increaseUnlockOrder: optional. An array of layer ids. When this layer is unlocked for the first time, the unlockOrder value for any not-yet-unlocked layers in this list increases. This can be used to make them harder to unlock.

      • shouldNotify: optional. A function to return true if this layer should be highlighted in the tree. The layer will automatically be highlighted if you can buy an upgrade whether you have this or not.

      • glowColor: optional. The color that this layer will be highlighted if it should notify. The default is red. You can use this if you want several different notification types!

      • componentStyles: optional. An object that contains a set of functions returning CSS objects. Each of these will be applied to any components on the layer with the type of its id. Example:

      js
      componentStyles: {
           "challenge"() { return {'height': '200px'} },
           "prestige-button"() { return {'color': '#AA66AA'} }
      -}
      • deactivated: optional, if this is true, hasUpgrade, hasChallenge, hasAchievement, and hasMilestone will return false for things in the layer, and you will be unable to buy or click things on the layer. You will have to disable effects of buyables, the innate layer effect, and possibly other things yourself.

      Custom Prestige type

      (All of these can also be used by other prestige types)

      • getResetGain(): mostly for custom prestige type. Returns how many points you should get if you reset now. You can call getResetGain(this.layer, useType = "static") or similar to calculate what your gain would be under another prestige type (provided you have all of the required features in the layer).

      • getNextAt(canMax=false): mostly for custom prestige type. Returns how many of the base currency you need to get to the next point. canMax is an optional variable used with Static-ish layers to differentiate between if it's looking for the first point you can reset at, or the requirement for any gain at all (Supporting both is good). You can also call getNextAt(this.layer, canMax=false, useType = "static") or similar to calculate what your next at would be under another prestige type (provided you have all of the required features in the layer).

      • canReset(): mostly for custom prestige type. Return true only if you have the resources required to do a prestige here.

      • prestigeNotify(): mostly for custom prestige types, returns true if this layer should be subtly highlighted to indicate you can prestige for a meaningful gain.

      - +}
      • deactivated: optional, if this is true, hasUpgrade, hasChallenge, hasAchievement, and hasMilestone will return false for things in the layer, and you will be unable to buy or click things on the layer. You will have to disable effects of buyables, the innate layer effect, and possibly other things yourself.

      Custom Prestige type

      (All of these can also be used by other prestige types)

      • getResetGain(): mostly for custom prestige type. Returns how many points you should get if you reset now. You can call getResetGain(this.layer, useType = "static") or similar to calculate what your gain would be under another prestige type (provided you have all of the required features in the layer).

      • getNextAt(canMax=false): mostly for custom prestige type. Returns how many of the base currency you need to get to the next point. canMax is an optional variable used with Static-ish layers to differentiate between if it's looking for the first point you can reset at, or the requirement for any gain at all (Supporting both is good). You can also call getNextAt(this.layer, canMax=false, useType = "static") or similar to calculate what your next at would be under another prestige type (provided you have all of the required features in the layer).

      • canReset(): mostly for custom prestige type. Return true only if you have the resources required to do a prestige here.

      • prestigeNotify(): mostly for custom prestige types, returns true if this layer should be subtly highlighted to indicate you can prestige for a meaningful gain.

    + \ No newline at end of file diff --git a/public/kronos/docs/main-mod-info.html b/public/kronos/docs/main-mod-info.html index 04ab48797..d9170eb59 100644 --- a/public/kronos/docs/main-mod-info.html +++ b/public/kronos/docs/main-mod-info.html @@ -6,12 +6,12 @@ mod.js | The Paper Pilot - + - + - + @@ -50,12 +50,12 @@ -
    Skip to content

    mod.js

    Most of the non-layer code and data that you're likely to edit is here in mod.js. Everything in mod.js will not be altered by updates, besides the addition of new things.

    Here's a breakdown of what's in it:

    • modInfo is where most of the basic configuration for the mod is. It contains:

      • name: The name of your mod. (a string)

      • id: The id for your mod, a unique string that is used to determine savefile location. Be sure to set it when you start making a mod, and don't change it later because it will erase all saves.

      • author: The name of the author, displayed in the info tab.

      • pointsName: This changes what is displayed instead of "points" for the main currency. (It does not affect it in the code.)

      • discordName, discordLink: If you have a Discord server or other discussion place, you can add a link to it.

        "discordName" is the text on the link, and "discordLink" is the url of an invite. If you're using a Discord invite, please make sure it's set to never expire.

      • offlineLimit: The maximum amount of offline time that the player can accumulate, in hours. Any extra time is lost. (a number)

        This is useful because most of these mods are fast-paced enough that too much offline time ruins the balance, such as the time in between updates. That is why I suggest developers disable offline time on their own savefile.

      • initialStartPoints: A Decimal for the amount of points a new player should start with.

    • VERSION is used to describe the current version of your mod. It contains:

      • num: The mod's version number, displayed at the top right of the tree tab.
      • name: The version's name, displayed alongside the number in the info tab.
    • changelog is the HTML displayed in the changelog tab. If this gets particularly long, it might be good to put in a separate file (be sure to add the file to index.html)

    • doNotCallTheseFunctionsEveryTick is very important, if you are adding non-standard functions. TMT calls every function anywhere in "layers" every tick to store the result, unless specifically told not to. Functions that have are used to do an action need to be identified. "Official" functions (those in the documentation) are all fine, but if you make any new ones, add their names to this array.

    js
    // (The ones here are examples, all official functions are already taken care of)
    +    
    Skip to content

    mod.js

    Most of the non-layer code and data that you're likely to edit is here in mod.js. Everything in mod.js will not be altered by updates, besides the addition of new things.

    Here's a breakdown of what's in it:

    • modInfo is where most of the basic configuration for the mod is. It contains:

      • name: The name of your mod. (a string)

      • id: The id for your mod, a unique string that is used to determine savefile location. Be sure to set it when you start making a mod, and don't change it later because it will erase all saves.

      • author: The name of the author, displayed in the info tab.

      • pointsName: This changes what is displayed instead of "points" for the main currency. (It does not affect it in the code.)

      • discordName, discordLink: If you have a Discord server or other discussion place, you can add a link to it.

        "discordName" is the text on the link, and "discordLink" is the url of an invite. If you're using a Discord invite, please make sure it's set to never expire.

      • offlineLimit: The maximum amount of offline time that the player can accumulate, in hours. Any extra time is lost. (a number)

        This is useful because most of these mods are fast-paced enough that too much offline time ruins the balance, such as the time in between updates. That is why I suggest developers disable offline time on their own savefile.

      • initialStartPoints: A Decimal for the amount of points a new player should start with.

    • VERSION is used to describe the current version of your mod. It contains:

      • num: The mod's version number, displayed at the top right of the tree tab.
      • name: The version's name, displayed alongside the number in the info tab.
    • changelog is the HTML displayed in the changelog tab. If this gets particularly long, it might be good to put in a separate file (be sure to add the file to index.html)

    • doNotCallTheseFunctionsEveryTick is very important, if you are adding non-standard functions. TMT calls every function anywhere in "layers" every tick to store the result, unless specifically told not to. Functions that have are used to do an action need to be identified. "Official" functions (those in the documentation) are all fine, but if you make any new ones, add their names to this array.

    js
    // (The ones here are examples, all official functions are already taken care of)
     var doNotCallTheseFunctionsEveryTick = ["doReset", "buy", "onPurchase", "blowUpEverything"]
    • getStartPoints(): A function to determine the amount of points the player starts with after a reset. (returns a Decimal value)

    • canGenPoints(): A function returning a boolean for if points should be generated. Use this if you want an upgrade to unlock generating points.

    • getPointGen(): A function that calculates your points per second. Anything that affects your point gain should go into the calculation here.

    • addedPlayerData(): A function that returns any non-layer-related data that you want to be added to the save data and "player" object.

    js
    function addedPlayerData() { return {
     	weather: "Yes",
     	happiness: new Decimal(72),
    -}}
    • displayThings: An array of functions used to display extra things at the top of the tree tab. Each function returns a string, which is a line to display (with basic HTML support). If a function returns nothing, nothing is displayed (and it doesn't take up a line).

    • isEndgame(): A function to determine if the player has reached the end of the game, at which point the "you win!" screen appears.

    Less important things beyond this point!

    • maxTickLength(): Returns the maximum tick length, in milliseconds. Only really useful if you have something that reduces over time, which long ticks mess up (usually a challenge).

    • fixOldSave(): Can be used to modify a save file when loading into a new version of the game. Use this to undo inflation, never forcibly hard reset your players.

    - +}}
    • displayThings: An array of functions used to display extra things at the top of the tree tab. Each function returns a string, which is a line to display (with basic HTML support). If a function returns nothing, nothing is displayed (and it doesn't take up a line).

    • isEndgame(): A function to determine if the player has reached the end of the game, at which point the "you win!" screen appears.

    Less important things beyond this point!

    • maxTickLength(): Returns the maximum tick length, in milliseconds. Only really useful if you have something that reduces over time, which long ticks mess up (usually a challenge).

    • fixOldSave(): Can be used to modify a save file when loading into a new version of the game. Use this to undo inflation, never forcibly hard reset your players.

    + \ No newline at end of file diff --git a/public/kronos/docs/milestones.html b/public/kronos/docs/milestones.html index ebbfe43b8..630867231 100644 --- a/public/kronos/docs/milestones.html +++ b/public/kronos/docs/milestones.html @@ -6,12 +6,12 @@ Milestones | The Paper Pilot - + - + - + @@ -50,15 +50,15 @@ -
    Skip to content

    Milestones

    Milestones are awarded to the player when they meet a certain goal, and give some benefit. Milestones should be formatted like this:

    js
    milestones: {
    +    
    Skip to content

    Milestones

    Milestones are awarded to the player when they meet a certain goal, and give some benefit. Milestones should be formatted like this:

    js
    milestones: {
         0: {
             requirementDescription: "123 waffles",
             effectDescription: "blah",
             done() { return player.w.points.gte(123) }
         }
         etc
    -}

    You can use hasMilestone(layer, id) to determine if the player has a given milestone

    Milestone features:

    • requirementDescription: A string describing the requirement for unlocking this milestone. Suggestion: Use a "total". It can also be a function that returns updating text. Can use basic HTML.

    • effectDescription: A string describing the reward for having the milestone. You will have to implement the reward elsewhere. It can also be a function that returns updating text. Can use basic HTML.

    • done(): A function returning a boolean to determine if the milestone should be awarded.

    • toggles: optional. Creates toggle buttons that appear on the milestone when it is unlocked. The toggles can toggle a given boolean value in a layer. It is defined as an array of paired items, one pair per toggle. The first is the internal name of the layer the value being toggled is stored in, and the second is the internal name of the variable to toggle. (e.g. [["b", "auto"], ["g", "auto"])

      Tip: Toggles are not de-set if the milestone becomes locked! In this case, you should also check if the player has the milestone.

    • style: optional. Applies CSS to this milestone, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • unlocked(): optional. A function returning a boolean to determine if the milestone should be shown. If absent, it is always shown.

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the milestone was stored under, for convenient access. The milestone in the example's id is 0.

    Disaable milestone popups by adding milestonePopups: false to the layer.

    - +}

    You can use hasMilestone(layer, id) to determine if the player has a given milestone

    Milestone features:

    • requirementDescription: A string describing the requirement for unlocking this milestone. Suggestion: Use a "total". It can also be a function that returns updating text. Can use basic HTML.

    • effectDescription: A string describing the reward for having the milestone. You will have to implement the reward elsewhere. It can also be a function that returns updating text. Can use basic HTML.

    • done(): A function returning a boolean to determine if the milestone should be awarded.

    • toggles: optional. Creates toggle buttons that appear on the milestone when it is unlocked. The toggles can toggle a given boolean value in a layer. It is defined as an array of paired items, one pair per toggle. The first is the internal name of the layer the value being toggled is stored in, and the second is the internal name of the variable to toggle. (e.g. [["b", "auto"], ["g", "auto"])

      Tip: Toggles are not de-set if the milestone becomes locked! In this case, you should also check if the player has the milestone.

    • style: optional. Applies CSS to this milestone, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • unlocked(): optional. A function returning a boolean to determine if the milestone should be shown. If absent, it is always shown.

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the milestone was stored under, for convenient access. The milestone in the example's id is 0.

    Disaable milestone popups by adding milestonePopups: false to the layer.

    + \ No newline at end of file diff --git a/public/kronos/docs/particles.html b/public/kronos/docs/particles.html index 5b73bf0c9..b9e07bab6 100644 --- a/public/kronos/docs/particles.html +++ b/public/kronos/docs/particles.html @@ -6,12 +6,12 @@ Particles | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
    Skip to content

    Particles

    Particles are free-floating elements that can move and have many different behaviors. They can also interact with the mouse.

    To make particles, use makeParticles(particle, amount). particle is a particle-defining object, with features as explained below. There is also makeShinies, which uses different defaults and creates stationary particles at a random location. There are also a few other useful things listed at the end.

    js
    
    +    
    Skip to content

    Particles

    Particles are free-floating elements that can move and have many different behaviors. They can also interact with the mouse.

    To make particles, use makeParticles(particle, amount). particle is a particle-defining object, with features as explained below. There is also makeShinies, which uses different defaults and creates stationary particles at a random location. There are also a few other useful things listed at the end.

    js
    
     const myParticle {
         image:"options_wheel.png",
         spread: 20,
    @@ -60,8 +60,8 @@
             return (Math.random() + 1.2) * 8 
         },
         etc...
    -}

    Features can be functions or constant. These features will be called when each particle is made, with an id argument, which is assigned based on which of the amount particles being spawned this is. All of these are optional, with a default value.

    All distances are in pixels and angles are in degrees, with 0 being up and going clockwise.

    • time: The amount of time, in seconds, that the particle will last. Default is 3.

    • fadeOutTime: The amount of seconds that fading out at the end should take (part of the total lifetime). Default is 1.

    • fadeInTime: The amount of seconds that fading in should take (part of the total lifetime). Default is 0.

    • image: The image the particle should display. "" will display no image. Default is a generic particle.

    • text: Displays text on the particle. Can use basic HTML.

    • style: Lets you apply other CSS styling to the particle.

    • width, height: The dimensions of the particle. Default is 35 and 35.

    • color: Sets the color of the image to this color.

    • angle: The angle that the particle should face. Default is 0.

    • dir: The initial angle that the particles should move in, before spread is factored in. Default is whatever angle is.

    • spread: If there are several particles, they will be spread out by this many degrees, centered on dir. Default is 30.

    • rotation: The amount that the (visual) angle of the particle should change by. Default is 0.

    • speed: The starting speed of the particle. Default is 15.

    • gravity: The amount the particle should accelerate downwards. Default is 0.

    • x, y: The starting coordinates of the particle. Default is at the mouse position.

    • offset: How far from the start each particle should appear. Default is 10.

    • xVel, yVel: Set initially based on other properties, then used to update movement.

    • layer: When changing tabs, if leaving the layer tab, this particle will be erased.

    • You can add other features to particles, but you must impliment their effects yourself.

    Function features: These stay as functions and are for more advanced things. They are optional.

    • update(): Called each tick. Lets you do more advanced visual and movement behaviors by changing other properties.
    • onClick(), onMouseOver(), onMouseLeave(): Called when the particle is interacted with.

    Other useful things that are not features of the particle object:

    • setDir(particle, dir), setSpeed(particle, speed): Set the speed/direction on a particle.
    • clearParticles(check): Function to delete particles. With no check, it deletes all particles. Check is a function that takes a particle, and returns true if that particle should be deleted.
    • You can use Vue.delete(particles, this.id) to make a particle delete itself.
    • mouseX and mouseY are variables that track the mouse position.
    • sin(x), cos(x), tan(x): functions that do these operations, with x in degrees. (Instead of radians).
    • asin(x), acos(x), atan(x): functions that do these operations, with the returned value in degrees. (instead of radians).
    - +}

    Features can be functions or constant. These features will be called when each particle is made, with an id argument, which is assigned based on which of the amount particles being spawned this is. All of these are optional, with a default value.

    All distances are in pixels and angles are in degrees, with 0 being up and going clockwise.

    • time: The amount of time, in seconds, that the particle will last. Default is 3.

    • fadeOutTime: The amount of seconds that fading out at the end should take (part of the total lifetime). Default is 1.

    • fadeInTime: The amount of seconds that fading in should take (part of the total lifetime). Default is 0.

    • image: The image the particle should display. "" will display no image. Default is a generic particle.

    • text: Displays text on the particle. Can use basic HTML.

    • style: Lets you apply other CSS styling to the particle.

    • width, height: The dimensions of the particle. Default is 35 and 35.

    • color: Sets the color of the image to this color.

    • angle: The angle that the particle should face. Default is 0.

    • dir: The initial angle that the particles should move in, before spread is factored in. Default is whatever angle is.

    • spread: If there are several particles, they will be spread out by this many degrees, centered on dir. Default is 30.

    • rotation: The amount that the (visual) angle of the particle should change by. Default is 0.

    • speed: The starting speed of the particle. Default is 15.

    • gravity: The amount the particle should accelerate downwards. Default is 0.

    • x, y: The starting coordinates of the particle. Default is at the mouse position.

    • offset: How far from the start each particle should appear. Default is 10.

    • xVel, yVel: Set initially based on other properties, then used to update movement.

    • layer: When changing tabs, if leaving the layer tab, this particle will be erased.

    • You can add other features to particles, but you must impliment their effects yourself.

    Function features: These stay as functions and are for more advanced things. They are optional.

    • update(): Called each tick. Lets you do more advanced visual and movement behaviors by changing other properties.
    • onClick(), onMouseOver(), onMouseLeave(): Called when the particle is interacted with.

    Other useful things that are not features of the particle object:

    • setDir(particle, dir), setSpeed(particle, speed): Set the speed/direction on a particle.
    • clearParticles(check): Function to delete particles. With no check, it deletes all particles. Check is a function that takes a particle, and returns true if that particle should be deleted.
    • You can use Vue.delete(particles, this.id) to make a particle delete itself.
    • mouseX and mouseY are variables that track the mouse position.
    • sin(x), cos(x), tan(x): functions that do these operations, with x in degrees. (Instead of radians).
    • asin(x), acos(x), atan(x): functions that do these operations, with the returned value in degrees. (instead of radians).
    + \ No newline at end of file diff --git a/public/kronos/docs/subtabs-and-microtabs.html b/public/kronos/docs/subtabs-and-microtabs.html index aafb4a162..b74b7df2e 100644 --- a/public/kronos/docs/subtabs-and-microtabs.html +++ b/public/kronos/docs/subtabs-and-microtabs.html @@ -6,12 +6,12 @@ Subtabs and Microtabs | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
    Skip to content

    Subtabs and Microtabs

    Subtabs are separate sections of a tab that you can view by selecting one at the top of the tab. Microtabs are smaller areas that function in much the same way. You can also embed layers inside of subtabs/microtabs.

    Subtabs are defined by using the tab format like this, where each element of tabFormat is given the name of that subtab:

    js
    tabFormat: {
    +    
    Skip to content

    Subtabs and Microtabs

    Subtabs are separate sections of a tab that you can view by selecting one at the top of the tab. Microtabs are smaller areas that function in much the same way. You can also embed layers inside of subtabs/microtabs.

    Subtabs are defined by using the tab format like this, where each element of tabFormat is given the name of that subtab:

    js
    tabFormat: {
         "Main tab": {
             content: [tab format things],
             *subtab features*
    @@ -74,8 +74,8 @@
         otherStuff: {
             // There could be another set of microtabs here
         }
    -}

    Normal subtabs and microtab subtabs both use the same features:

    Features:

    • content: The tab layout code for the subtab, in the tab layout format.

    • style: optional. Applies CSS to the whole subtab when switched to, in the form of an "CSS Object", where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • buttonStyle: optional. A CSS object, which affects the appearance of the button for that subtab.

    • unlocked(): optional. a function to determine if the button for this subtab should be visible. By default, a subtab is always unlocked. You can't use the "this" keyword in this function.

    • shouldNotify()/prestigeNotify(): optional, if true, the tab button will be highlighted to notify the player that there is something there.

    • glowColor: optional, specifies the color that the subtab glows. If this subtab is causing the main layer to node glow (and it would't otherwise) the node also glows this color. Is NOT overridden by embedding a layer.

    • embedLayer: SIGNIFICANT, the id of another layer. If you have this, it will override "content", "style" and "shouldNotify", instead displaying the entire layer in the subtab.

    - +}

    Normal subtabs and microtab subtabs both use the same features:

    Features:

    • content: The tab layout code for the subtab, in the tab layout format.

    • style: optional. Applies CSS to the whole subtab when switched to, in the form of an "CSS Object", where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • buttonStyle: optional. A CSS object, which affects the appearance of the button for that subtab.

    • unlocked(): optional. a function to determine if the button for this subtab should be visible. By default, a subtab is always unlocked. You can't use the "this" keyword in this function.

    • shouldNotify()/prestigeNotify(): optional, if true, the tab button will be highlighted to notify the player that there is something there.

    • glowColor: optional, specifies the color that the subtab glows. If this subtab is causing the main layer to node glow (and it would't otherwise) the node also glows this color. Is NOT overridden by embedding a layer.

    • embedLayer: SIGNIFICANT, the id of another layer. If you have this, it will override "content", "style" and "shouldNotify", instead displaying the entire layer in the subtab.

    + \ No newline at end of file diff --git a/public/kronos/docs/trees-and-tree-customization.html b/public/kronos/docs/trees-and-tree-customization.html index 7a1b0f85a..22b629bd2 100644 --- a/public/kronos/docs/trees-and-tree-customization.html +++ b/public/kronos/docs/trees-and-tree-customization.html @@ -6,12 +6,12 @@ Trees and tree customization | The Paper Pilot - + - + - + @@ -50,10 +50,10 @@ -
    Skip to content

    Trees and tree customization

    If you want to have something beyond the standard tree on the left tab, you can do that in tree.js. You can change the layout of the tree, including making non-layer nodes, change it into something other than a tree, or hide the left tab altogether. This also introduces the "tree" component, which can be used in your layers as well.

    layoutInfo

    The most important part is layoutInfo, containing:

    • startTab: The id of the default tab to show on the left at the start.
    • showTree: True if the tree tab should be shown at the start of the game. (The other tab will fill the whole page)
    • treeLayout: If present, overrides the tree layout and places nodes as you describe instead (explained in the next section).

    Additionally, if you want the main layout to not be a tree, you can edit the "tree-tab" layer at the bottom of tree.js to modify it just like a normal layer's tab. You can even switch between left tabs, using showNavTab(layer) to make that layer appear on the left.

    Trees

    The tree component is defined as an array of arrays of names of layers or nodes to show in the tree. They work just like layers/ nodes in the main tree (but branches between nodes will only work on the first node if you have duplicates.)

    Here is an example tree:

    js
    [["p"],
    +    
    Skip to content

    Trees and tree customization

    If you want to have something beyond the standard tree on the left tab, you can do that in tree.js. You can change the layout of the tree, including making non-layer nodes, change it into something other than a tree, or hide the left tab altogether. This also introduces the "tree" component, which can be used in your layers as well.

    layoutInfo

    The most important part is layoutInfo, containing:

    • startTab: The id of the default tab to show on the left at the start.
    • showTree: True if the tree tab should be shown at the start of the game. (The other tab will fill the whole page)
    • treeLayout: If present, overrides the tree layout and places nodes as you describe instead (explained in the next section).

    Additionally, if you want the main layout to not be a tree, you can edit the "tree-tab" layer at the bottom of tree.js to modify it just like a normal layer's tab. You can even switch between left tabs, using showNavTab(layer) to make that layer appear on the left.

    Trees

    The tree component is defined as an array of arrays of names of layers or nodes to show in the tree. They work just like layers/ nodes in the main tree (but branches between nodes will only work on the first node if you have duplicates.)

    Here is an example tree:

    js
    [["p"],
      ["left", "blank", "right", "blank"]
    - ["a", "b", "blank", "c", "weirdButton"]]

    Nodes

    Nodes are non-layer buttons that can go in trees. They are defined similarly to layers, but with addNode instead of addLayer.

    Features:

    • color: optional, The node's color. (A string in hex format with a #)

    • symbol: optional The text on the button (The id capitalized by default)

    • canClick(): Returns true if the player can click the node. ()

    • onClick(): The function called when the node is clicked.

    • layerShown(): optional, A function returning a bool which determines if this node should be visible. It can also return "ghost", which will hide the layer, but its node will still take up space in its tree.

    • branches: optional. An array of layer/node ids. On a tree, a line will appear from this node to all of the nodes in the list. Alternatively, an entry in the array can be a 2-element array consisting of the id and a color value. The color value can either be a string with a hex color code, or a number from 1-3 (theme-affected colors).

    • nodeStyle: optional. A CSS object, where the keys are CSS attributes, which styles this node on the tree.

    • tooltip() / tooltipLocked(): optional. Functions that return text, which is the tooltip for the node when the layer is unlocked or locked, respectively. By default the tooltips behave the same as in the original Prestige Tree.

    • row: optional, the row that this node appears in (for the default tree).

    • position: optional, Determines the horizontal position of the layer in its row in a default tree. By default, it uses the id, and layers/nodes are sorted in alphabetical order.

    - + ["a", "b", "blank", "c", "weirdButton"]]

    Nodes

    Nodes are non-layer buttons that can go in trees. They are defined similarly to layers, but with addNode instead of addLayer.

    Features:

    • color: optional, The node's color. (A string in hex format with a #)

    • symbol: optional The text on the button (The id capitalized by default)

    • canClick(): Returns true if the player can click the node. ()

    • onClick(): The function called when the node is clicked.

    • layerShown(): optional, A function returning a bool which determines if this node should be visible. It can also return "ghost", which will hide the layer, but its node will still take up space in its tree.

    • branches: optional. An array of layer/node ids. On a tree, a line will appear from this node to all of the nodes in the list. Alternatively, an entry in the array can be a 2-element array consisting of the id and a color value. The color value can either be a string with a hex color code, or a number from 1-3 (theme-affected colors).

    • nodeStyle: optional. A CSS object, where the keys are CSS attributes, which styles this node on the tree.

    • tooltip() / tooltipLocked(): optional. Functions that return text, which is the tooltip for the node when the layer is unlocked or locked, respectively. By default the tooltips behave the same as in the original Prestige Tree.

    • row: optional, the row that this node appears in (for the default tree).

    • position: optional, Determines the horizontal position of the layer in its row in a default tree. By default, it uses the id, and layers/nodes are sorted in alphabetical order.

    + \ No newline at end of file diff --git a/public/kronos/docs/updating-tmt.html b/public/kronos/docs/updating-tmt.html index c69b0917a..8d68ada74 100644 --- a/public/kronos/docs/updating-tmt.html +++ b/public/kronos/docs/updating-tmt.html @@ -6,12 +6,12 @@ Updating The Modding Tree | The Paper Pilot - + - + - + @@ -50,8 +50,8 @@ -
    Skip to content

    Updating The Modding Tree

    This tutorial assumes that you have used the Getting Started Tutorial, and are using Github Desktop and VSCode for your mod.

    Here's what you have to do when there's a TMT update:

    1. Look at the changelog. It will warn you if the update will break anything or require any changes. Decide if you want to try to update.

    2. Open Github Desktop, and at the top middle, click "fetch origin". This will make Github Desktop get information about the update.

    3. Click where it says "current branch: master" at the top middle, and at the bottom of the thing that appears, click "choose a branch to merge into master".

    4. Select upstream/master. It will likely say there are conflicts, but you have tools to resolve them. Click "Merge upstream/master into master".

    5. A conflict happens when the things you're trying to merge have both made changes in the same place. Click "open in Visual Studio Code" next to the first file.

    6. Scroll down through the file, and look for the parts highlighted in red and green. One of these is your code, and the other is some code that will be modified by the update. Do your best to try to edit things to keep the updated changes, but keep your content.

    7. Continue to do this for all remaining changes.

    8. Do any other changes required by the update, run the game, fix issues, etc.

    - +
    Skip to content

    Updating The Modding Tree

    This tutorial assumes that you have used the Getting Started Tutorial, and are using Github Desktop and VSCode for your mod.

    Here's what you have to do when there's a TMT update:

    1. Look at the changelog. It will warn you if the update will break anything or require any changes. Decide if you want to try to update.

    2. Open Github Desktop, and at the top middle, click "fetch origin". This will make Github Desktop get information about the update.

    3. Click where it says "current branch: master" at the top middle, and at the bottom of the thing that appears, click "choose a branch to merge into master".

    4. Select upstream/master. It will likely say there are conflicts, but you have tools to resolve them. Click "Merge upstream/master into master".

    5. A conflict happens when the things you're trying to merge have both made changes in the same place. Click "open in Visual Studio Code" next to the first file.

    6. Scroll down through the file, and look for the parts highlighted in red and green. One of these is your code, and the other is some code that will be modified by the update. Do your best to try to edit things to keep the updated changes, but keep your content.

    7. Continue to do this for all remaining changes.

    8. Do any other changes required by the update, run the game, fix issues, etc.

    + \ No newline at end of file diff --git a/public/kronos/docs/upgrades.html b/public/kronos/docs/upgrades.html index 724881487..885ef9236 100644 --- a/public/kronos/docs/upgrades.html +++ b/public/kronos/docs/upgrades.html @@ -6,12 +6,12 @@ Upgrades | The Paper Pilot - + - + - + @@ -50,15 +50,15 @@ -
    Skip to content

    Upgrades

    Useful functions for dealing with Upgrades and implementing their effects:

    • hasUpgrade(layer, id): determine if the player has the upgrade
    • upgradeEffect(layer, id): Returns the current effects of the upgrade, if any
    • buyUpgrade(layer, id): Buys an upgrade directly (if affordable)

    Hint: Basic point gain is calculated in mod.js's "getPointGen" function.

    Upgrades are stored in the following format:

    js
    upgrades: {
    +    
    Skip to content

    Upgrades

    Useful functions for dealing with Upgrades and implementing their effects:

    • hasUpgrade(layer, id): determine if the player has the upgrade
    • upgradeEffect(layer, id): Returns the current effects of the upgrade, if any
    • buyUpgrade(layer, id): Buys an upgrade directly (if affordable)

    Hint: Basic point gain is calculated in mod.js's "getPointGen" function.

    Upgrades are stored in the following format:

    js
    upgrades: {
         11: {
             description: "Blah",
             cost: new Decimal(100),
             etc
         },
         etc
    -}

    Usually, upgrades should have an id where the first digit is the row and the second digit is the column.

    Individual upgrades can have these features:

    • title: optional. Displayed at the top in a larger font. It can also be a function that returns updating text. Can use basic HTML.

    • description: A description of the upgrade's effect. You will also have to implement the effect where it is applied. It can also be a function that returns updating text. Can use basic HTML.

    • effect(): optional. A function that calculates and returns the current values of any bonuses from the upgrade. Can return a value or an object containing multiple values.

    • effectDisplay(): optional. A function that returns a display of the current effects of the upgrade with formatting. Default displays nothing. Can use basic HTML.

    • fullDisplay(): OVERRIDE. Overrides the other displays and descriptions, and lets you set the full text for the upgrade. Can use basic HTML.

    • cost: A Decimal for the cost of the upgrade. By default, upgrades cost the main prestige currency for the layer.

    • unlocked(): optional. A function returning a bool to determine if the upgrade is visible or not. Default is unlocked.

    • onPurchase(): optional. This function will be called when the upgrade is purchased. Good for upgrades like "makes this layer act like it was unlocked first".

    • style: optional. Applies CSS to this upgrade, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the upgrade was stored under, for convenient access. The upgrade in the example's id is 11.

    By default, upgrades use the main prestige currency for the layer. You can include these to change them (but it needs to be a Decimal):

    • currencyDisplayName: optional. The name to display for the currency for the upgrade.

    • currencyInternalName: optional. The internal name for that currency.

    • currencyLayer: optional. The internal name of the layer that currency is stored in. If it's not in a layer (like Points), omit. If it's not stored directly in a layer, instead use the next feature.

    • currencyLocation: optional. If your currency is stored in something inside a layer (e.g. a buyable's amount), you can access it this way. This is a function returning the object in "player" that contains the value (like player[this.layer].buyables)

    If you want to do something more complicated like upgrades that cost two currencies, you can override the purchase system with these (and you need to use fullDisplay as well)

    • canAfford(): OVERRIDE, a function determining if you are able to buy the upgrade

    • pay(): OVERRIDE, a function that reduces your currencies when you buy the upgrade

    - +}

    Usually, upgrades should have an id where the first digit is the row and the second digit is the column.

    Individual upgrades can have these features:

    • title: optional. Displayed at the top in a larger font. It can also be a function that returns updating text. Can use basic HTML.

    • description: A description of the upgrade's effect. You will also have to implement the effect where it is applied. It can also be a function that returns updating text. Can use basic HTML.

    • effect(): optional. A function that calculates and returns the current values of any bonuses from the upgrade. Can return a value or an object containing multiple values.

    • effectDisplay(): optional. A function that returns a display of the current effects of the upgrade with formatting. Default displays nothing. Can use basic HTML.

    • fullDisplay(): OVERRIDE. Overrides the other displays and descriptions, and lets you set the full text for the upgrade. Can use basic HTML.

    • cost: A Decimal for the cost of the upgrade. By default, upgrades cost the main prestige currency for the layer.

    • unlocked(): optional. A function returning a bool to determine if the upgrade is visible or not. Default is unlocked.

    • onPurchase(): optional. This function will be called when the upgrade is purchased. Good for upgrades like "makes this layer act like it was unlocked first".

    • style: optional. Applies CSS to this upgrade, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the upgrade was stored under, for convenient access. The upgrade in the example's id is 11.

    By default, upgrades use the main prestige currency for the layer. You can include these to change them (but it needs to be a Decimal):

    • currencyDisplayName: optional. The name to display for the currency for the upgrade.

    • currencyInternalName: optional. The internal name for that currency.

    • currencyLayer: optional. The internal name of the layer that currency is stored in. If it's not in a layer (like Points), omit. If it's not stored directly in a layer, instead use the next feature.

    • currencyLocation: optional. If your currency is stored in something inside a layer (e.g. a buyable's amount), you can access it this way. This is a function returning the object in "player" that contains the value (like player[this.layer].buyables)

    If you want to do something more complicated like upgrades that cost two currencies, you can override the purchase system with these (and you need to use fullDisplay as well)

    • canAfford(): OVERRIDE, a function determining if you are able to buy the upgrade

    • pay(): OVERRIDE, a function that reduces your currencies when you buy the upgrade

    + \ No newline at end of file diff --git a/public/lit/Old Things/2.0-format-changes.html b/public/lit/Old Things/2.0-format-changes.html index 9977f87d4..bdafc5e8a 100644 --- a/public/lit/Old Things/2.0-format-changes.html +++ b/public/lit/Old Things/2.0-format-changes.html @@ -6,12 +6,12 @@ 2.0 format changes | The Paper Pilot - + - + - + @@ -50,8 +50,8 @@ -
    Skip to content

    2.0 format changes

    • Temp format is changed from temp.something[layer] to temp[layer].something, for consistency
    • Challenges are now saved as an object with the amount of completions in each spot. (This will break saves.)
    • effectDisplay in Challenges and Upgrades no longer takes an argument, and neither does effect for Buyables
    • Buyable cost can take an argument for amount of buyables, but it needs to function if no argument is supplied (it should do the cost for the next purchase).
    • Generation of Points now happens in the main game loop (not in a layer update function), enabled by canGenPoints in game.js.
    • Changed fullLayerReset to layerDataReset, which takes an array of names of values to keep

    In addition, many names were changed, mostly expanding abbreviations:

    All instances of:

    • chall -> challenge
    • unl -> unlocked
    • upg -> upgrade (besides CSS)
    • amt -> amount
    • desc -> description
    • resCeil -> roundUpCost
    • order -> unlockOrder
    • incr_order -> increaseUnlockOrder

    Challenges:

    • desc -> challengeDescription
    • reward -> rewardDescription
    • effect -> rewardEffect
    • effectDisplay -> rewardDisplay
    • active -> challengeActive
    - +
    Skip to content

    2.0 format changes

    • Temp format is changed from temp.something[layer] to temp[layer].something, for consistency
    • Challenges are now saved as an object with the amount of completions in each spot. (This will break saves.)
    • effectDisplay in Challenges and Upgrades no longer takes an argument, and neither does effect for Buyables
    • Buyable cost can take an argument for amount of buyables, but it needs to function if no argument is supplied (it should do the cost for the next purchase).
    • Generation of Points now happens in the main game loop (not in a layer update function), enabled by canGenPoints in game.js.
    • Changed fullLayerReset to layerDataReset, which takes an array of names of values to keep

    In addition, many names were changed, mostly expanding abbreviations:

    All instances of:

    • chall -> challenge
    • unl -> unlocked
    • upg -> upgrade (besides CSS)
    • amt -> amount
    • desc -> description
    • resCeil -> roundUpCost
    • order -> unlockOrder
    • incr_order -> increaseUnlockOrder

    Challenges:

    • desc -> challengeDescription
    • reward -> rewardDescription
    • effect -> rewardEffect
    • effectDisplay -> rewardDisplay
    • active -> challengeActive
    + \ No newline at end of file diff --git a/public/lit/README.html b/public/lit/README.html index e8e38349d..87bb4d86f 100644 --- a/public/lit/README.html +++ b/public/lit/README.html @@ -6,12 +6,12 @@ Kronos | The Paper Pilot - + - + - + @@ -50,8 +50,8 @@ -
    Skip to content

    Kronos

    Play here.

    Updating the website:

    • git submodule update --remote
    • git add -A
    • git commit -m "Updated kronos"
    • git push
    - +
    Skip to content

    Kronos

    Play here.

    Updating the website:

    • git submodule update --remote
    • git add -A
    • git commit -m "Updated kronos"
    • git push
    + \ No newline at end of file diff --git a/public/lit/changelog.html b/public/lit/changelog.html index 1ebabb064..2e7d57b53 100644 --- a/public/lit/changelog.html +++ b/public/lit/changelog.html @@ -6,12 +6,12 @@ The Modding Tree changelog: | The Paper Pilot - + - + - + @@ -50,8 +50,8 @@ -
    Skip to content

    The Modding Tree changelog:

    v2.π: Incrementally Updated - 2/5/21

    • Performance improvements.
    • Fixed tooltips overlapping with the top display.
    • Clicking a popup dismisses it immediately.
    • Added support for bulk challenge completions.
    • "Best" is updated automatically.
    • Fixed keeping Decimal values on reset.
    • Code reorganization and style improvements by fudo.

    v2.3.5 - 12/21/20

    • Added resetTime, which tracks the time since a layer prestiged or was reset.
    • A layer node will be highlighted red if one of its subtabs is highlighted red.
    • Fixed issues with keeping challenges, buyables, and clickables on reset.
    • Improved the unlocking of custom layers.
    • Other minor fixes.

    v2.3.4 - 12/16/20

    • Added a node image feature.
    • Resource display now always shows the amount of the currency the layer's gain is based on.
    • Added spacing between tree nodes.
    • Another attempt to fix tooltip flickering.

    v2.3.3 - 12/13/20

    • Fixed the first node in a row always taking up space.
    • layerShown is now optional.
    • All prestige types can now use features for custom prestige types.

    v2.3.2 - 12/13/20

    • Fixed achievement/milestone popups.

    v2.3.1 - 12/12/20

    • Another attempt to fix flickering tooltips.
    • The "this" keyword should work everywhere except tabFormat arrays (although I may have missed some things).
    • Fixed tree branches not updating when scrolling on the right-side tab.
    • Fixed a spacing issue when a node's symbol is ""
    • Removed some old, unneeded files.

    v2.3: Cooler and Newer Edition - 12/10/20

    • Added achievement/milestone popups (thank you to Jacorb for this contribution!)
    • The changelog tab is back, and can be set in mod.js.
    • Layer nodes and respec buttons will not be clicked by pressing "enter".
    • Possible fix for flickering tooltips and strange transitions.
    • The victory screen text is configurable.
    • Added image and textStyle features to achievements.
    • Added an argument to use specific rows in an "upgrades" component.
    • Fixed the comma appearing in the main display when there was no effectDescription
    • Added the ability to easily make a tab that is a collection of layers in subtabs.
    • Improved spacing for embedding layers with subtabs into subtabs.

    v2.2.8 - 12/03/20

    • Double-clicking a layer node brings you to the main subtab for that layer.
    • Attempted to fix challenges visually updating a different way.
    • Added a softcap function for use in formulas.
    • Added displayRow feature, which lets layers be shown somewhere separate from where they are in the reset order (e.g. side layers)
    • Fixed autoupgrade issue.

    v2.2.7 - 11/30/20

    • Added autoUpgrade feature.
    • resource-display now shows resource gain per second if passiveGain is active.
    • Fixed formatting issues on some large numbers.
    • Better support for using classed objects in player and in layers/tmp.
    • Made hard resetting more effective.
    • Removed Herobrine from getStartClickables.

    v2.2.6 - 11/30/20

    • Added goalDescription for challenges and made the new "canComplete" system the standard.
    • Another attempt to fix challenges not visually updating.
    • Fixed side layers not appearing.
    • Fixed getStartClickables again.

    v2.2.5 - 11/29/20

    • Added features for overriding the displays and costs/goals of upgrades and challenges to make them fully custom.
    • best, total, and unlocked are always automatically added to layerData (but best and total will only display if you add them yourself).
    • Fixed getStartClickables.

    v2.2.4 - 11/28/20

    • Added softcap and softcapPower features (for Normal layers)
    • Offline time limit and default max tick length were fixed (previously the limits were 1000x too large)
    • Added fixOldSaves.
    • You can use HTML in main-display.
    • Fixed a number of minor oddities.

    v2.2.3 - 11/28/20

    • Layers will be highlighted if you can finish a challenge.
    • The "can complete challenge" color now overrides the "already completed" color.
    • Button nodes now work as side "layers".
    • Setting a tooltip to "" hides it entirely.

    v2.2.2 - 11/22/20

    • Fixed right half of the screen being unclickable in some circumstances.
    • Fixed tree branches being offset.
    • Fix to lastSafeTab.

    v2.2.1 - 11/7/20

    • Added a small highlight to layers you can meaningfully prestige on.
    • Added passiveGeneration and autoPrestige features to standardize prestige automation. (The old ways still work, but the new ones work better with other things)
    • Improved milestones visually a bit.
    • "best" and "total" are now only displayed if present in startData.
    • Fixed issues with things not updating visually. (Thank you to to Jacorb!)
    • Side layers and button nodes can now be highlighted.
    • Updated docs on the new tree-related features.

    v2.2: Uprooted - 11/7/20

    • You can now embed a layer inside of a subtab or microtab!
    • Added support for hiding or reformatting the tree tab
    • Added non-layer button nodes
    • Added shouldNotify to subtab/microtab buttons. (You can make them highlighted)
    • Added commas to large exponents.
    • Upgrades now only show "currently" if they have an effectDisplay (so not for constant effects).
    • Achievements are part of the default tab format.
    • NaN is now handled more intelligently.
    • Renamed files, and moved less relevant ones to another folder.
    • The "hide completed challenges" setting now only hides challenges at max completions.
    • Thank you to thepaperpilot for fixing errors in docs and improving the infobox appearance!
    • Many other minor fixes.

    v2.1.4 - 10/25/20

    • Added an infobox component. Thank you to thepaperpilot for this contribution!
    • Layer type is now optional, and defaults to "none".
    • Improved the look of bars and tab buttons.
    • Improved spacing between layer nodes (also thanks to thepaperpilot!)
    • Fixed the "blank" component breaking if only specifying the height.
    • Fixed some numbers not displaying with enough digits.
    • Made a few more things able to be functions.
    • A few other minor fixes.

    v2.1.3.1 - 10/21/20

    • Fixed the update function.

    v2.1.3 - 10/21/20

    • gainMult and gainExp are now optional.
    • Layer unlocking is now kept on reset.
    • Game should start up faster.
    • Layer updates now have a determined order and starts with earlier-rowed layers.
    • Automation now has a determined order and starts with later-rowed layers.
    • Fixed issues with resetting clickables and challenges.
    • Commas should no longer appear in the decimal places of a number.
    • Fixed potential issue in displaying the tree.

    v2.1.2 - 10/19/20

    • Added buyUpgrade function (buyUpg still works though)
    • Added author name to modInfo.
    • Fix to crash caused when the name of a subtab or microtab is changed.
    • Fixes to outdated information in docs.
    • Improvements to Discord links.
    • Thank you to thepaperpilot for contributing to this update!

    v2.1.1 - 10/17/20

    • Added resource-display component, which displays the base currency for the prestige layer, as well as the best and/or total of this layer's prestige currency.
    • Fixed the value for the base currency not updating in resource-display.

    v2.1: We should have thought of this sooner! - 10/17/20

    • Moved most of the code users will want to edit to mod.js, added documentation for it.
      • Specifically, modInfo, VERSION, canGenPoints, getPointGen, and maxTickLength
    • Added getStartPoints()
    • Added the ability to store non-layer-related data
    • Added the ability to display more things at the top of the tree tab below points.
    • Made the endgame condition customizable
    • Added "sell one" and "sell all" buttons for buyables.
    • Moved the old "game" to demo.js, and replaced it with a minimal game that won't cause issues when edited.
    • Fixed issues with version number
    • Fixed number formatting issue making things like "10e9" appear.

    v2.0.5 - 10/16/20

    • Made more features (including prestige parameters) able to be dynamic.
    • Layer nodes can be hidden but still take up space with "ghost" visibility
    • Added clickableEffect for real.
    • Fixed some visual issues with bars.
    • A few other minor tweaks and improvements.

    v2.0.4 - 10/16/20

    • Fixed HTML on buttons interfering with clicking on them.

    v2.0.3 - 10/16/20

    • Fixed hotkeys not displaying in info.
    • Fixed the game supressing all external hotkeys.
    • You can use more things as currencies for upgrade costs and challenge goals using currencyLocation.
    • Added maxTickLength, which can be used to prevent offline time or tab-switching from breaking time-limit based mechanics.
    • Made buyable respec buttons and clickable "master" buttons their own components, and gave them a hide/show feature.
    • Added a general "tooltip" feature for achievements.

    v2.0.2 - 10/15/20

    • Branches are now dynamic (they can be functions).
    • Fixed a crash related to offline time.
    • Fixed links being too wide.

    v2.0.1 - 10/15/20

    • Fixed side layers appearing multiple times.

    v2.0: The Pinnacle of Achievement Mountain - 10/15/20

    • Added progress bars, which are highly customizable and can be horizontal or vertical!
    • Added "side layers", displayed smaller and off to the side, and don't get reset by default. They can be used for global achievements and statistics. Speaking of which...
    • Added achievements!
    • Added clickables, a more generalized variant of buyables.
    • Almost every value in layer data can be either a function or a constant value!
    • Added support for multiple completions of challenges.
    • Added "none" prestige type, which removes the need for any other prestige-related features.
    • The points display and other gui elements stay at the top of the screen when the tree scrolls.
    • Added getter/setter functions for the amounts and effects of most Big Features
    • Moved modInfo to game.js, added a spot in modInfo for a Discord link, changelog link. Also added a separate mod version from the TMT version in VERSION.
    • Tree structure is based on layer data, no index.html editing is needed.
    • Tmp does not need to be manually updated.
    • You don't have to have the same amount of upgrades in every row (and challs and buyables)
    • "unlocked" is optional for all Big Components (defaults to true).
    • All displays will update correctly.
    • Changelog is no longer in index.html at all.
    • Generation of Points now happens in the main game loop
    • Changed the reset functions to make keeping things easier
    • Renamed many things to increase readability (see the list in the link below)
    • Improved documentation based on feedback

    v1.3.5:

    • Completely automated convertToDecimal, now you never have to worry about it again.
    • Branches can be defined without a color id. But they can also use hex values for color ids!
    • Created a tutorial for getting started with TMT and Github.
    • Page title is now automatically taken from mod name.

    v1.3.4 - 10/8/20

    • Added "midsection" feature to add things to a tab's layout while still keeping the standard layout.
    • Fix for being able to buy more buyables than you should.

    v1.3.3 - 10/7/20

    • Fix for the "order of operations" issue in temp.

    v1.3.1 - 10/7/20

    • Added custom CSS and tooltips for Layer Nodes.
    • Added custom CSS for upgrades, buyables, milestones, and challenges, both individually and layer-wide.
    • You can now use HTML in most display text!
    • You can now make milestones unlockable and not display immediately.
    • Fixed importing saves, and issue with upgrades not appearing, and probably more.
    • Optional "name" layer feature, used in confirmation messages.

    v1.3: Tabception... ception! - 10/7/20

    • Added subtabs! And also a Micro-tab component to let you make smaller subtab-esque areas anywhere.
    • Added a "custom" prestige formula type, and a number of features to support it.
    • Added points/sec display (can be disabled).
    • Added h-line, v-line and image-display components, plus components for individual upgrades, challenges, and milestones.
    • Added upgEffect, buyableEffect, and challEffect functions.
    • Added "hide completed challenges" setting.
    • Moved old changelogs to a separate place.
    • Fixed hasMilestone and incr_order.
    • Static layers now show the currency amount needed for the next one if you can buy max.

    v1.2.4 - 10/4/20

    • Layers are now highlighted if you can buy an upgrade, and a new feature, shouldNotify, lets you make it highlight other ways.
    • Fixed bugs with hasUpg, hasChall, hasMilestone, and inChallenge.
    • Changed the sample code to use the above functions for convenience.

    v1.2.3 - 10/3/20

    • Added a row component, which displays a list of objects in a row.
    • Added a column component, which displays a list of objects in a column (useful within a row).
    • Changed blanks to have a customizable width and height.

    v1.2: This Changes Everything! - 10/3/20

    • Many layer features can now be static values or functions. (This made some formats change, which will break old things)
    • You can now use the "this" keyword, to make code easier to transfer when making new layers.
    • Also added "this.layer", which is the current layer's name, and works on existing subfeatures (e.g. individual upgrades) as well! Subfeatures also have "this.id".
    • Fixed a big save issue. If you use a unique mod id, your save will never conflict with other mods.
    • Added a configurable offline time limit in modinfo at the top of index.html. (default 1 hour)
    • Added a few minor features, and updated the docs with new information.

    v1.1.1:

    • You can define hotkeys directly from layer config.

    v1.1: Enhanced Edition

    • Added "Buyables", which can function like Space Buildings or Enhancers.
    • Custom CSS can now be used on any component! Make the third argument an object with CSS parameters.
    • Lots of minor good things.

    v1.0:

    • First release.
    - +
    Skip to content

    The Modding Tree changelog:

    v2.π: Incrementally Updated - 2/5/21

    • Performance improvements.
    • Fixed tooltips overlapping with the top display.
    • Clicking a popup dismisses it immediately.
    • Added support for bulk challenge completions.
    • "Best" is updated automatically.
    • Fixed keeping Decimal values on reset.
    • Code reorganization and style improvements by fudo.

    v2.3.5 - 12/21/20

    • Added resetTime, which tracks the time since a layer prestiged or was reset.
    • A layer node will be highlighted red if one of its subtabs is highlighted red.
    • Fixed issues with keeping challenges, buyables, and clickables on reset.
    • Improved the unlocking of custom layers.
    • Other minor fixes.

    v2.3.4 - 12/16/20

    • Added a node image feature.
    • Resource display now always shows the amount of the currency the layer's gain is based on.
    • Added spacing between tree nodes.
    • Another attempt to fix tooltip flickering.

    v2.3.3 - 12/13/20

    • Fixed the first node in a row always taking up space.
    • layerShown is now optional.
    • All prestige types can now use features for custom prestige types.

    v2.3.2 - 12/13/20

    • Fixed achievement/milestone popups.

    v2.3.1 - 12/12/20

    • Another attempt to fix flickering tooltips.
    • The "this" keyword should work everywhere except tabFormat arrays (although I may have missed some things).
    • Fixed tree branches not updating when scrolling on the right-side tab.
    • Fixed a spacing issue when a node's symbol is ""
    • Removed some old, unneeded files.

    v2.3: Cooler and Newer Edition - 12/10/20

    • Added achievement/milestone popups (thank you to Jacorb for this contribution!)
    • The changelog tab is back, and can be set in mod.js.
    • Layer nodes and respec buttons will not be clicked by pressing "enter".
    • Possible fix for flickering tooltips and strange transitions.
    • The victory screen text is configurable.
    • Added image and textStyle features to achievements.
    • Added an argument to use specific rows in an "upgrades" component.
    • Fixed the comma appearing in the main display when there was no effectDescription
    • Added the ability to easily make a tab that is a collection of layers in subtabs.
    • Improved spacing for embedding layers with subtabs into subtabs.

    v2.2.8 - 12/03/20

    • Double-clicking a layer node brings you to the main subtab for that layer.
    • Attempted to fix challenges visually updating a different way.
    • Added a softcap function for use in formulas.
    • Added displayRow feature, which lets layers be shown somewhere separate from where they are in the reset order (e.g. side layers)
    • Fixed autoupgrade issue.

    v2.2.7 - 11/30/20

    • Added autoUpgrade feature.
    • resource-display now shows resource gain per second if passiveGain is active.
    • Fixed formatting issues on some large numbers.
    • Better support for using classed objects in player and in layers/tmp.
    • Made hard resetting more effective.
    • Removed Herobrine from getStartClickables.

    v2.2.6 - 11/30/20

    • Added goalDescription for challenges and made the new "canComplete" system the standard.
    • Another attempt to fix challenges not visually updating.
    • Fixed side layers not appearing.
    • Fixed getStartClickables again.

    v2.2.5 - 11/29/20

    • Added features for overriding the displays and costs/goals of upgrades and challenges to make them fully custom.
    • best, total, and unlocked are always automatically added to layerData (but best and total will only display if you add them yourself).
    • Fixed getStartClickables.

    v2.2.4 - 11/28/20

    • Added softcap and softcapPower features (for Normal layers)
    • Offline time limit and default max tick length were fixed (previously the limits were 1000x too large)
    • Added fixOldSaves.
    • You can use HTML in main-display.
    • Fixed a number of minor oddities.

    v2.2.3 - 11/28/20

    • Layers will be highlighted if you can finish a challenge.
    • The "can complete challenge" color now overrides the "already completed" color.
    • Button nodes now work as side "layers".
    • Setting a tooltip to "" hides it entirely.

    v2.2.2 - 11/22/20

    • Fixed right half of the screen being unclickable in some circumstances.
    • Fixed tree branches being offset.
    • Fix to lastSafeTab.

    v2.2.1 - 11/7/20

    • Added a small highlight to layers you can meaningfully prestige on.
    • Added passiveGeneration and autoPrestige features to standardize prestige automation. (The old ways still work, but the new ones work better with other things)
    • Improved milestones visually a bit.
    • "best" and "total" are now only displayed if present in startData.
    • Fixed issues with things not updating visually. (Thank you to to Jacorb!)
    • Side layers and button nodes can now be highlighted.
    • Updated docs on the new tree-related features.

    v2.2: Uprooted - 11/7/20

    • You can now embed a layer inside of a subtab or microtab!
    • Added support for hiding or reformatting the tree tab
    • Added non-layer button nodes
    • Added shouldNotify to subtab/microtab buttons. (You can make them highlighted)
    • Added commas to large exponents.
    • Upgrades now only show "currently" if they have an effectDisplay (so not for constant effects).
    • Achievements are part of the default tab format.
    • NaN is now handled more intelligently.
    • Renamed files, and moved less relevant ones to another folder.
    • The "hide completed challenges" setting now only hides challenges at max completions.
    • Thank you to thepaperpilot for fixing errors in docs and improving the infobox appearance!
    • Many other minor fixes.

    v2.1.4 - 10/25/20

    • Added an infobox component. Thank you to thepaperpilot for this contribution!
    • Layer type is now optional, and defaults to "none".
    • Improved the look of bars and tab buttons.
    • Improved spacing between layer nodes (also thanks to thepaperpilot!)
    • Fixed the "blank" component breaking if only specifying the height.
    • Fixed some numbers not displaying with enough digits.
    • Made a few more things able to be functions.
    • A few other minor fixes.

    v2.1.3.1 - 10/21/20

    • Fixed the update function.

    v2.1.3 - 10/21/20

    • gainMult and gainExp are now optional.
    • Layer unlocking is now kept on reset.
    • Game should start up faster.
    • Layer updates now have a determined order and starts with earlier-rowed layers.
    • Automation now has a determined order and starts with later-rowed layers.
    • Fixed issues with resetting clickables and challenges.
    • Commas should no longer appear in the decimal places of a number.
    • Fixed potential issue in displaying the tree.

    v2.1.2 - 10/19/20

    • Added buyUpgrade function (buyUpg still works though)
    • Added author name to modInfo.
    • Fix to crash caused when the name of a subtab or microtab is changed.
    • Fixes to outdated information in docs.
    • Improvements to Discord links.
    • Thank you to thepaperpilot for contributing to this update!

    v2.1.1 - 10/17/20

    • Added resource-display component, which displays the base currency for the prestige layer, as well as the best and/or total of this layer's prestige currency.
    • Fixed the value for the base currency not updating in resource-display.

    v2.1: We should have thought of this sooner! - 10/17/20

    • Moved most of the code users will want to edit to mod.js, added documentation for it.
      • Specifically, modInfo, VERSION, canGenPoints, getPointGen, and maxTickLength
    • Added getStartPoints()
    • Added the ability to store non-layer-related data
    • Added the ability to display more things at the top of the tree tab below points.
    • Made the endgame condition customizable
    • Added "sell one" and "sell all" buttons for buyables.
    • Moved the old "game" to demo.js, and replaced it with a minimal game that won't cause issues when edited.
    • Fixed issues with version number
    • Fixed number formatting issue making things like "10e9" appear.

    v2.0.5 - 10/16/20

    • Made more features (including prestige parameters) able to be dynamic.
    • Layer nodes can be hidden but still take up space with "ghost" visibility
    • Added clickableEffect for real.
    • Fixed some visual issues with bars.
    • A few other minor tweaks and improvements.

    v2.0.4 - 10/16/20

    • Fixed HTML on buttons interfering with clicking on them.

    v2.0.3 - 10/16/20

    • Fixed hotkeys not displaying in info.
    • Fixed the game supressing all external hotkeys.
    • You can use more things as currencies for upgrade costs and challenge goals using currencyLocation.
    • Added maxTickLength, which can be used to prevent offline time or tab-switching from breaking time-limit based mechanics.
    • Made buyable respec buttons and clickable "master" buttons their own components, and gave them a hide/show feature.
    • Added a general "tooltip" feature for achievements.

    v2.0.2 - 10/15/20

    • Branches are now dynamic (they can be functions).
    • Fixed a crash related to offline time.
    • Fixed links being too wide.

    v2.0.1 - 10/15/20

    • Fixed side layers appearing multiple times.

    v2.0: The Pinnacle of Achievement Mountain - 10/15/20

    • Added progress bars, which are highly customizable and can be horizontal or vertical!
    • Added "side layers", displayed smaller and off to the side, and don't get reset by default. They can be used for global achievements and statistics. Speaking of which...
    • Added achievements!
    • Added clickables, a more generalized variant of buyables.
    • Almost every value in layer data can be either a function or a constant value!
    • Added support for multiple completions of challenges.
    • Added "none" prestige type, which removes the need for any other prestige-related features.
    • The points display and other gui elements stay at the top of the screen when the tree scrolls.
    • Added getter/setter functions for the amounts and effects of most Big Features
    • Moved modInfo to game.js, added a spot in modInfo for a Discord link, changelog link. Also added a separate mod version from the TMT version in VERSION.
    • Tree structure is based on layer data, no index.html editing is needed.
    • Tmp does not need to be manually updated.
    • You don't have to have the same amount of upgrades in every row (and challs and buyables)
    • "unlocked" is optional for all Big Components (defaults to true).
    • All displays will update correctly.
    • Changelog is no longer in index.html at all.
    • Generation of Points now happens in the main game loop
    • Changed the reset functions to make keeping things easier
    • Renamed many things to increase readability (see the list in the link below)
    • Improved documentation based on feedback

    v1.3.5:

    • Completely automated convertToDecimal, now you never have to worry about it again.
    • Branches can be defined without a color id. But they can also use hex values for color ids!
    • Created a tutorial for getting started with TMT and Github.
    • Page title is now automatically taken from mod name.

    v1.3.4 - 10/8/20

    • Added "midsection" feature to add things to a tab's layout while still keeping the standard layout.
    • Fix for being able to buy more buyables than you should.

    v1.3.3 - 10/7/20

    • Fix for the "order of operations" issue in temp.

    v1.3.1 - 10/7/20

    • Added custom CSS and tooltips for Layer Nodes.
    • Added custom CSS for upgrades, buyables, milestones, and challenges, both individually and layer-wide.
    • You can now use HTML in most display text!
    • You can now make milestones unlockable and not display immediately.
    • Fixed importing saves, and issue with upgrades not appearing, and probably more.
    • Optional "name" layer feature, used in confirmation messages.

    v1.3: Tabception... ception! - 10/7/20

    • Added subtabs! And also a Micro-tab component to let you make smaller subtab-esque areas anywhere.
    • Added a "custom" prestige formula type, and a number of features to support it.
    • Added points/sec display (can be disabled).
    • Added h-line, v-line and image-display components, plus components for individual upgrades, challenges, and milestones.
    • Added upgEffect, buyableEffect, and challEffect functions.
    • Added "hide completed challenges" setting.
    • Moved old changelogs to a separate place.
    • Fixed hasMilestone and incr_order.
    • Static layers now show the currency amount needed for the next one if you can buy max.

    v1.2.4 - 10/4/20

    • Layers are now highlighted if you can buy an upgrade, and a new feature, shouldNotify, lets you make it highlight other ways.
    • Fixed bugs with hasUpg, hasChall, hasMilestone, and inChallenge.
    • Changed the sample code to use the above functions for convenience.

    v1.2.3 - 10/3/20

    • Added a row component, which displays a list of objects in a row.
    • Added a column component, which displays a list of objects in a column (useful within a row).
    • Changed blanks to have a customizable width and height.

    v1.2: This Changes Everything! - 10/3/20

    • Many layer features can now be static values or functions. (This made some formats change, which will break old things)
    • You can now use the "this" keyword, to make code easier to transfer when making new layers.
    • Also added "this.layer", which is the current layer's name, and works on existing subfeatures (e.g. individual upgrades) as well! Subfeatures also have "this.id".
    • Fixed a big save issue. If you use a unique mod id, your save will never conflict with other mods.
    • Added a configurable offline time limit in modinfo at the top of index.html. (default 1 hour)
    • Added a few minor features, and updated the docs with new information.

    v1.1.1:

    • You can define hotkeys directly from layer config.

    v1.1: Enhanced Edition

    • Added "Buyables", which can function like Space Buildings or Enhancers.
    • Custom CSS can now be used on any component! Make the third argument an object with CSS parameters.
    • Lots of minor good things.

    v1.0:

    • First release.
    + \ No newline at end of file diff --git a/public/lit/docs/!general-info.html b/public/lit/docs/!general-info.html index 953d0a346..0daa0a099 100644 --- a/public/lit/docs/!general-info.html +++ b/public/lit/docs/!general-info.html @@ -6,12 +6,12 @@ The-Modding-Tree | The Paper Pilot - + - + - + @@ -50,8 +50,8 @@ -
    Skip to content

    The-Modding-Tree

    The main way to add content is through creating layers. You can either add a layer directly in the layers object in layerSupport.js, or declare it in another file and register it by calling addLayer(layername, layerdata). There is an example layer registration in layers.js showing the recommended method. It is just an example and can be freely deleted. You can also use it as a reference or a base for your own layers.

    The first thing you need to do is fill out the modInfo object at the top of mod.js to set your mod's name, ID (a string), and other information. A unique modId will prevent your mod's saves from conflicting with other mods. Note that changing this after people have started playing will reset their saves.

    Most of the time, you won't need to dive deep into the code to create things, but you still can if you really want to, for example to add new Vue components in v.js.

    The Modding Tree uses break_eternity.js to store large values. This means that many numbers are Decimal objects, and must be treated differently. For example, you have to use new Decimal(x) to create a Decimal value instead of a plain number, and perform operations on them by calling functions. e.g, instead of x = x + y, use x = x.add(y). Keep in mind this also applies to comparison operators, which should be replaced with calling the .gt, .gte, .lt, .lte, .eq, and .neq functions. See the break_eternity.js docs for more details on working with Decimal values.

    Almost all values can be either a constant value, or a dynamic value. Dynamic values are defined by putting a function that returns what the value should be at any given time.

    All display text can use basic HTML elements (But you can't use most Vue features there).

    While reading this documentation, the following key will be used when describing features:

    • No label: This is required and the game may crash if it isn't included.
    • sometimes required: This is may be required, depending on other things in the layer.
    • optional: You can leave this out if you don't intend to use that feature for the layer.
    • assigned automagically: This value will be set automatically and override any value you set.
    • deprecated: This feature is not recommended to be used anymore, and may be removed in future versions of TMT.

    Table of Contents

    General

    • Getting Started: Getting your own copy of the code set up with Github Desktop.
    • Main mod info: How to set up general things for your mod in mod.js.
    • Basic layer breakdown: Breaking down the components of a layer with minimal features.
    • Layer features: Explanations of all of the different properties that you can give a layer.
    • Custom Tab Layouts: An optional way to give your tabs a different layout. You can even create entirely new components to use.
    • Custom game layouts: You can get rid of the tree tab, add buttons and other things to the tree, or even customize the tab's layout like a layer tab.
    • Updating TMT: Using Github Desktop to update your mod's version of TMT.

    Common components

    • Upgrades: How to create upgrades for a layer.
    • Milestones: How to create milestones for a layer.
    • Buyables: Create rebuyable upgrades for your layer (with the option to make them respec-able). Can be used to make Enhancers or Space Buildings.
    • Clickables: A more generalized variant of buyables, for any kind of thing that is sometimes clickable. Between these and Buyables, you can do just about anything.

    Other components and features

    • Challenges: How to create challenges for a layer.
    • Bars: Display some information as a progress bar, gauge, or similar. They are highly customizable, and can be horizontal and vertical as well.
    • Subtabs and Microtabs: Create subtabs for your tabs, as well as "microtab" components that you can put inside the tabs. You can even use them to embed a layer inside another layer!
    • Achievements: How to create achievements for a layer (or for the whole game).
    • Infoboxes: Boxes containing text that can be shown or hidden.
    • Trees: Make your own trees. You can make non-layer button nodes too!
    - +
    Skip to content

    The-Modding-Tree

    The main way to add content is through creating layers. You can either add a layer directly in the layers object in layerSupport.js, or declare it in another file and register it by calling addLayer(layername, layerdata). There is an example layer registration in layers.js showing the recommended method. It is just an example and can be freely deleted. You can also use it as a reference or a base for your own layers.

    The first thing you need to do is fill out the modInfo object at the top of mod.js to set your mod's name, ID (a string), and other information. A unique modId will prevent your mod's saves from conflicting with other mods. Note that changing this after people have started playing will reset their saves.

    Most of the time, you won't need to dive deep into the code to create things, but you still can if you really want to, for example to add new Vue components in v.js.

    The Modding Tree uses break_eternity.js to store large values. This means that many numbers are Decimal objects, and must be treated differently. For example, you have to use new Decimal(x) to create a Decimal value instead of a plain number, and perform operations on them by calling functions. e.g, instead of x = x + y, use x = x.add(y). Keep in mind this also applies to comparison operators, which should be replaced with calling the .gt, .gte, .lt, .lte, .eq, and .neq functions. See the break_eternity.js docs for more details on working with Decimal values.

    Almost all values can be either a constant value, or a dynamic value. Dynamic values are defined by putting a function that returns what the value should be at any given time.

    All display text can use basic HTML elements (But you can't use most Vue features there).

    While reading this documentation, the following key will be used when describing features:

    • No label: This is required and the game may crash if it isn't included.
    • sometimes required: This is may be required, depending on other things in the layer.
    • optional: You can leave this out if you don't intend to use that feature for the layer.
    • assigned automagically: This value will be set automatically and override any value you set.
    • deprecated: This feature is not recommended to be used anymore, and may be removed in future versions of TMT.

    Table of Contents

    General

    • Getting Started: Getting your own copy of the code set up with Github Desktop.
    • Main mod info: How to set up general things for your mod in mod.js.
    • Basic layer breakdown: Breaking down the components of a layer with minimal features.
    • Layer features: Explanations of all of the different properties that you can give a layer.
    • Custom Tab Layouts: An optional way to give your tabs a different layout. You can even create entirely new components to use.
    • Custom game layouts: You can get rid of the tree tab, add buttons and other things to the tree, or even customize the tab's layout like a layer tab.
    • Updating TMT: Using Github Desktop to update your mod's version of TMT.

    Common components

    • Upgrades: How to create upgrades for a layer.
    • Milestones: How to create milestones for a layer.
    • Buyables: Create rebuyable upgrades for your layer (with the option to make them respec-able). Can be used to make Enhancers or Space Buildings.
    • Clickables: A more generalized variant of buyables, for any kind of thing that is sometimes clickable. Between these and Buyables, you can do just about anything.

    Other components and features

    • Challenges: How to create challenges for a layer.
    • Bars: Display some information as a progress bar, gauge, or similar. They are highly customizable, and can be horizontal and vertical as well.
    • Subtabs and Microtabs: Create subtabs for your tabs, as well as "microtab" components that you can put inside the tabs. You can even use them to embed a layer inside another layer!
    • Achievements: How to create achievements for a layer (or for the whole game).
    • Infoboxes: Boxes containing text that can be shown or hidden.
    • Trees: Make your own trees. You can make non-layer button nodes too!
    + \ No newline at end of file diff --git a/public/lit/docs/achievements.html b/public/lit/docs/achievements.html index 3d92a11f2..013c532c0 100644 --- a/public/lit/docs/achievements.html +++ b/public/lit/docs/achievements.html @@ -6,12 +6,12 @@ Achievements | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
    Skip to content

    Achievements

    Achievements are awarded to the player when they meet a certain goal, and optionally give some benefit. Currently they are pretty basic, but additional features will be added later to help.

    You can make global achievements by putting them in a side layer by making its row equal to "side" instead of a number.

    Useful functions for dealing with achievements and implementing their effects:

    • hasAchievement(layer, id): determine if the player has the Achievement.
    • achievementEffect(layer, id): Returns the current effects of the achievement, if any.

    Achievements should be formatted like this:

    js
    achievements: {
    +    
    Skip to content

    Achievements

    Achievements are awarded to the player when they meet a certain goal, and optionally give some benefit. Currently they are pretty basic, but additional features will be added later to help.

    You can make global achievements by putting them in a side layer by making its row equal to "side" instead of a number.

    Useful functions for dealing with achievements and implementing their effects:

    • hasAchievement(layer, id): determine if the player has the Achievement.
    • achievementEffect(layer, id): Returns the current effects of the achievement, if any.

    Achievements should be formatted like this:

    js
    achievements: {
         rows: # of rows,
         cols: # of columns,
         11: {
    @@ -58,8 +58,8 @@
             more features
         },
         etc
    -}

    Each achievement should have an id where the first digit is the row and the second digit is the column.

    Individual achievement can have these features:

    • name: optional. displayed at the top of the achievement. The only visible text. It can also be a function that returns updating text. Can use basic HTML.

    • done(): A function returning a boolean to determine if the achievement should be awarded.

    • tooltip: Default tooltip for the achievement, appears when it is hovered over. Should convey the goal and any reward for completing the achievement. It can also be a function that returns updating text. Can use basic HTML. Setting this to "" disables the tooltip.

    • effect(): optional. A function that calculates and returns the current values of any bonuses from the achievement. Can return a value or an object containing multiple values.

    • unlocked(): optional. A function returning a bool to determine if the achievement is visible or not. Default is unlocked.

    • onComplete() - optional. this function will be called when the achievement is completed.

    • image: optional, puts the image from the given URL (relative or absolute) in the achievement

    • style: optional. Applies CSS to this achievement, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • textStyle: optional. Applies CSS to the text, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the achievement was stored under, for convenient access. The achievement in the example's id is 11.

    • goalTooltip: optional, deprecated. Appears when the achievement is hovered over and locked, overrides the basic tooltip. This is to display the goal (or a hint). It can also be a function that returns updating text. Can use basic HTML.

    • doneTooltip: optional, deprecated. Appears when the achievement is hovered over and completed, overrides the basic tooltip. This can display what the player achieved (the goal), and the rewards, if any. It can also be a function that returns updating text. Can use basic HTML.

    Disable achievement popups by adding achievementsPopups: false to the layer.

    - +}

    Each achievement should have an id where the first digit is the row and the second digit is the column.

    Individual achievement can have these features:

    • name: optional. displayed at the top of the achievement. The only visible text. It can also be a function that returns updating text. Can use basic HTML.

    • done(): A function returning a boolean to determine if the achievement should be awarded.

    • tooltip: Default tooltip for the achievement, appears when it is hovered over. Should convey the goal and any reward for completing the achievement. It can also be a function that returns updating text. Can use basic HTML. Setting this to "" disables the tooltip.

    • effect(): optional. A function that calculates and returns the current values of any bonuses from the achievement. Can return a value or an object containing multiple values.

    • unlocked(): optional. A function returning a bool to determine if the achievement is visible or not. Default is unlocked.

    • onComplete() - optional. this function will be called when the achievement is completed.

    • image: optional, puts the image from the given URL (relative or absolute) in the achievement

    • style: optional. Applies CSS to this achievement, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • textStyle: optional. Applies CSS to the text, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the achievement was stored under, for convenient access. The achievement in the example's id is 11.

    • goalTooltip: optional, deprecated. Appears when the achievement is hovered over and locked, overrides the basic tooltip. This is to display the goal (or a hint). It can also be a function that returns updating text. Can use basic HTML.

    • doneTooltip: optional, deprecated. Appears when the achievement is hovered over and completed, overrides the basic tooltip. This can display what the player achieved (the goal), and the rewards, if any. It can also be a function that returns updating text. Can use basic HTML.

    Disable achievement popups by adding achievementsPopups: false to the layer.

    + \ No newline at end of file diff --git a/public/lit/docs/bars.html b/public/lit/docs/bars.html index b6548dc79..070df25cc 100644 --- a/public/lit/docs/bars.html +++ b/public/lit/docs/bars.html @@ -6,12 +6,12 @@ Bars | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
    Skip to content

    Bars

    Bars let you display information in a more direct way. It can be a progress bar, health bar, capacity gauge, or anything else.

    Bars are defined like other Big Features:

    js
    bars: {
    +    
    Skip to content

    Bars

    Bars let you display information in a more direct way. It can be a progress bar, health bar, capacity gauge, or anything else.

    Bars are defined like other Big Features:

    js
    bars: {
         bigBar: {
             direction: RIGHT,
             width: 200,
    @@ -59,8 +59,8 @@
             etc
         },
         etc
    -}

    Features:

    • direction: UP, DOWN, LEFT, or RIGHT (not strings). Determines the direction that the bar is filled as it progresses. RIGHT means from left to right.

    • width, height: The size in pixels of the bar, but as numbers (no "px" at the end).

    • progress(): A function that returns the portion of the bar that is filled, from "empty" at 0 to "full" at 1, updating automatically. (Nothing bad happens if the value goes out of these bounds, and it can be a number or Decimal)

    • display(): optional. A function that returns text to be displayed on top of the bar, can use HTML.

    • unlocked(): optional. A function returning a bool to determine if the bar is visible or not. Default is unlocked.

    • baseStyle, fillStyle, borderStyle, textStyle: Optional, Apply CSS to the unfilled portion, filled portion, border, and display text on the bar, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the bar was stored under, for convenient access. The bar in the example's id is "bigBar".

    - +}

    Features:

    • direction: UP, DOWN, LEFT, or RIGHT (not strings). Determines the direction that the bar is filled as it progresses. RIGHT means from left to right.

    • width, height: The size in pixels of the bar, but as numbers (no "px" at the end).

    • progress(): A function that returns the portion of the bar that is filled, from "empty" at 0 to "full" at 1, updating automatically. (Nothing bad happens if the value goes out of these bounds, and it can be a number or Decimal)

    • display(): optional. A function that returns text to be displayed on top of the bar, can use HTML.

    • unlocked(): optional. A function returning a bool to determine if the bar is visible or not. Default is unlocked.

    • baseStyle, fillStyle, borderStyle, textStyle: Optional, Apply CSS to the unfilled portion, filled portion, border, and display text on the bar, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the bar was stored under, for convenient access. The bar in the example's id is "bigBar".

    + \ No newline at end of file diff --git a/public/lit/docs/basic-layer-breakdown.html b/public/lit/docs/basic-layer-breakdown.html index 440581f98..ccb02f7a7 100644 --- a/public/lit/docs/basic-layer-breakdown.html +++ b/public/lit/docs/basic-layer-breakdown.html @@ -6,12 +6,12 @@ Basic layer breakdown | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
    Skip to content

    Basic layer breakdown

    This is a very minimal layer with minimal features. Most things will require additional features.

    js
    addLayer("p", {
    +    
    Skip to content

    Basic layer breakdown

    This is a very minimal layer with minimal features. Most things will require additional features.

    js
    addLayer("p", {
         startData() { return {                  // startData is a function that returns default data for a layer. 
             unlocked: true,                     // You can add more variables here to add them to your layer.
             points: new Decimal(0),             // "points" is the internal name for the main resource of the layer.
    @@ -77,8 +77,8 @@
         },
     
         layerShown() { return true }            // Returns a bool for if this layer's node should be visible in the tree.
    -})
    - +})
    + \ No newline at end of file diff --git a/public/lit/docs/buyables.html b/public/lit/docs/buyables.html index 4522fcddb..e9243f0ba 100644 --- a/public/lit/docs/buyables.html +++ b/public/lit/docs/buyables.html @@ -6,12 +6,12 @@ Buyables | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
    Skip to content

    Buyables

    Buyables are usually things that can be bought multiple times with scaling costs. If you set a respec function, the player can reset the purchases to get their currency back.

    The amount of a buyable owned is a Decimal.

    Useful functions for dealing with buyables and implementing their effects:

    • getBuyableAmount(layer, id): get the amount of the buyable the player has
    • setBuyableAmount(layer, id, amount): set the amount of the buyable the player has
    • buyableEffect(layer, id): Returns the current effects of the buyable, if any.

    Buyables should be formatted like this:

    js
    buyables: {
    +    
    Skip to content

    Buyables

    Buyables are usually things that can be bought multiple times with scaling costs. If you set a respec function, the player can reset the purchases to get their currency back.

    The amount of a buyable owned is a Decimal.

    Useful functions for dealing with buyables and implementing their effects:

    • getBuyableAmount(layer, id): get the amount of the buyable the player has
    • setBuyableAmount(layer, id, amount): set the amount of the buyable the player has
    • buyableEffect(layer, id): Returns the current effects of the buyable, if any.

    Buyables should be formatted like this:

    js
    buyables: {
         rows: # of rows,
         cols: # of columns,
         11: {
    @@ -64,8 +64,8 @@
             etc
         },
         etc
    -}

    Features:

    • title: optional. displayed at the top in a larger font. It can also be a function that returns updating text.

    • cost(): cost for buying the next buyable. Can have an optional argument "x" to calculate the cost of the x+1th object, but needs to use "current amount" as a default value for x. (x is a Decimal). Can return an object if there are multiple currencies.

    • effect(): optional. A function that calculates and returns the current values of bonuses of this buyable. Can return a value or an object containing multiple values.

    • display(): A function returning everything that should be displayed on the buyable after the title, likely including the description, amount bought, cost, and current effect. Can use basic HTML.

    • unlocked(): optional. A function returning a bool to determine if the buyable is visible or not. Default is unlocked.

    • canAfford(): A function returning a bool to determine if you can buy one of the buyables.

    • buy(): A function that implements buying one of the buyable, including spending the currency.

    • buyMax(): optional. A function that implements buying as many of the buyable as possible.

    • style: optional. Applies CSS to this buyable, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the buyable was stored under, for convenient access. The buyable in the example's id is 11.

    Sell One/Sell All:

    Including a sellOne or sellAll function will cause an additional button to appear beneath the buyable. They are functionally identical, but "sell one" appears above "sell all". You can also use them for other things.

    • sellOne/sellAll(): optional. Called when the button is pressed. The standard use would be to decrease/reset the amount of the buyable, and possibly return some currency to the player.

    • canSellOne/canSellAll(): optional. booleans determining whether or not to show the buttons. If "canSellOne/All" is absent but "sellOne/All" is present, the appropriate button will always show.

    - +}

    Features:

    • title: optional. displayed at the top in a larger font. It can also be a function that returns updating text.

    • cost(): cost for buying the next buyable. Can have an optional argument "x" to calculate the cost of the x+1th object, but needs to use "current amount" as a default value for x. (x is a Decimal). Can return an object if there are multiple currencies.

    • effect(): optional. A function that calculates and returns the current values of bonuses of this buyable. Can return a value or an object containing multiple values.

    • display(): A function returning everything that should be displayed on the buyable after the title, likely including the description, amount bought, cost, and current effect. Can use basic HTML.

    • unlocked(): optional. A function returning a bool to determine if the buyable is visible or not. Default is unlocked.

    • canAfford(): A function returning a bool to determine if you can buy one of the buyables.

    • buy(): A function that implements buying one of the buyable, including spending the currency.

    • buyMax(): optional. A function that implements buying as many of the buyable as possible.

    • style: optional. Applies CSS to this buyable, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the buyable was stored under, for convenient access. The buyable in the example's id is 11.

    Sell One/Sell All:

    Including a sellOne or sellAll function will cause an additional button to appear beneath the buyable. They are functionally identical, but "sell one" appears above "sell all". You can also use them for other things.

    • sellOne/sellAll(): optional. Called when the button is pressed. The standard use would be to decrease/reset the amount of the buyable, and possibly return some currency to the player.

    • canSellOne/canSellAll(): optional. booleans determining whether or not to show the buttons. If "canSellOne/All" is absent but "sellOne/All" is present, the appropriate button will always show.

    + \ No newline at end of file diff --git a/public/lit/docs/challenges.html b/public/lit/docs/challenges.html index dfa9bbdda..f940a50f6 100644 --- a/public/lit/docs/challenges.html +++ b/public/lit/docs/challenges.html @@ -6,12 +6,12 @@ Challenges | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
    Skip to content

    Challenges

    Challenges can have fully customizable win conditions. Useful functions for dealing with Challenges and implementing their effects:

    • inChallenge(layer, id): determine if the player is in a given challenge (or another challenge on the same layer that counts as this one).
    • hasChallenge(layer, id): determine if the player has completed the challenge.
    • challengeCompletions(layer, id): determine how many times the player completed the challenge.
    • challengeEffect(layer, id): Returns the current effects of the challenge, if any.

    Challenges are stored in the following format:

    js
    challenges: {
    +    
    Skip to content

    Challenges

    Challenges can have fully customizable win conditions. Useful functions for dealing with Challenges and implementing their effects:

    • inChallenge(layer, id): determine if the player is in a given challenge (or another challenge on the same layer that counts as this one).
    • hasChallenge(layer, id): determine if the player has completed the challenge.
    • challengeCompletions(layer, id): determine how many times the player completed the challenge.
    • challengeEffect(layer, id): Returns the current effects of the challenge, if any.

    Challenges are stored in the following format:

    js
    challenges: {
         rows: # of rows,
         cols: # of columns,
         11: {
    @@ -60,8 +60,8 @@
             etc
         },
         etc
    -}

    Each challenge should have an id where the first digit is the row and the second digit is the column.

    Individual Challenges can have these features:

    • name: Name of the challenge, can be a string or a function. Can use basic HTML.

    • challengeDescription: A description of what makes the challenge a challenge. You will need to implement these elsewhere. It can also be a function that returns updating text. Can use basic HTML.

    • goalDescription: A description of the win condition for the challenge. It can also be a function that returns updating text. Can use basic HTML. (Optional if using the old goal system)

    • canComplete(): A function that returns true if you meet the win condition for the challenge. Returning a number will allow bulk completing the challenge. (Optional if using the old goal system)

    • rewardDescription: A description of the reward's effect. You will also have to implement the effect where it is applied. It can also be a function that returns updating text. Can use basic HTML.

    • rewardEffect(): optional. A function that calculates and returns the current values of any bonuses from the reward. Can return a value or an object containing multiple values. Can use basic HTML.

    • rewardDisplay(): optional. A function that returns a display of the current effects of the reward with formatting. Default behavior is to just display the a number appropriately formatted.

    • fullDisplay(): OVERRIDE. Overrides the other displays and descriptions, and lets you set the full text for the challenge. Can use basic HTML.

    • unlocked(): optional. A function returning a bool to determine if the challenge is visible or not. Default is unlocked.

    • onComplete() - optional. this function will be called when the challenge is completed when previously incomplete.

    • countsAs: optional. If a challenge combines the effects of other challenges in this layer, you can use this. An array of challenge ids. The player is effectively in all of those challenges when in the current one.

    • completionLimit: optional. the amount of times you can complete this challenge. Default is 1 completion.

    • style: optional. Applies CSS to this challenge, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar

    • id: assigned automagically. It's the "key" which the challenge was stored under, for convenient access. The challenge in the example's id is 11.

    The old goal system uses these features:

    • goal: deprecated, A Decimal for the amount of currency required to beat the challenge. By default, the goal is in basic Points. The goal can also be a function if its value changes.

    • currencyDisplayName: deprecated. the name to display for the currency for the goal

    • currencyInternalName: deprecated. the internal name for that currency

    • currencyLayer: deprecated. the internal name of the layer that currency is stored in. If it's not in a layer, omit. If it's not stored directly in a layer, instead use the next feature.

    • currencyLocation(): deprecated. if your currency is stored in something inside a layer (e.g. a buyable's amount), you can access it this way. This is a function returning the object in "player" that contains the value (like player[this.layer].buyables)

    - +}

    Each challenge should have an id where the first digit is the row and the second digit is the column.

    Individual Challenges can have these features:

    • name: Name of the challenge, can be a string or a function. Can use basic HTML.

    • challengeDescription: A description of what makes the challenge a challenge. You will need to implement these elsewhere. It can also be a function that returns updating text. Can use basic HTML.

    • goalDescription: A description of the win condition for the challenge. It can also be a function that returns updating text. Can use basic HTML. (Optional if using the old goal system)

    • canComplete(): A function that returns true if you meet the win condition for the challenge. Returning a number will allow bulk completing the challenge. (Optional if using the old goal system)

    • rewardDescription: A description of the reward's effect. You will also have to implement the effect where it is applied. It can also be a function that returns updating text. Can use basic HTML.

    • rewardEffect(): optional. A function that calculates and returns the current values of any bonuses from the reward. Can return a value or an object containing multiple values. Can use basic HTML.

    • rewardDisplay(): optional. A function that returns a display of the current effects of the reward with formatting. Default behavior is to just display the a number appropriately formatted.

    • fullDisplay(): OVERRIDE. Overrides the other displays and descriptions, and lets you set the full text for the challenge. Can use basic HTML.

    • unlocked(): optional. A function returning a bool to determine if the challenge is visible or not. Default is unlocked.

    • onComplete() - optional. this function will be called when the challenge is completed when previously incomplete.

    • countsAs: optional. If a challenge combines the effects of other challenges in this layer, you can use this. An array of challenge ids. The player is effectively in all of those challenges when in the current one.

    • completionLimit: optional. the amount of times you can complete this challenge. Default is 1 completion.

    • style: optional. Applies CSS to this challenge, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar

    • id: assigned automagically. It's the "key" which the challenge was stored under, for convenient access. The challenge in the example's id is 11.

    The old goal system uses these features:

    • goal: deprecated, A Decimal for the amount of currency required to beat the challenge. By default, the goal is in basic Points. The goal can also be a function if its value changes.

    • currencyDisplayName: deprecated. the name to display for the currency for the goal

    • currencyInternalName: deprecated. the internal name for that currency

    • currencyLayer: deprecated. the internal name of the layer that currency is stored in. If it's not in a layer, omit. If it's not stored directly in a layer, instead use the next feature.

    • currencyLocation(): deprecated. if your currency is stored in something inside a layer (e.g. a buyable's amount), you can access it this way. This is a function returning the object in "player" that contains the value (like player[this.layer].buyables)

    + \ No newline at end of file diff --git a/public/lit/docs/clickables.html b/public/lit/docs/clickables.html index 30f7f2288..ad45ba328 100644 --- a/public/lit/docs/clickables.html +++ b/public/lit/docs/clickables.html @@ -6,12 +6,12 @@ Clickables | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
    Skip to content

    Clickables

    Clickables are any kind of thing that you can click for an effect. They're a more generalized version of Buyables.

    DO NOT USE THESE TO MAKE THINGS THAT YOU CLICK REPEATEDLY FOR A BONUS BECAUSE THOSE ARE AWFUL.

    There are several differences between the two. One is that a buyable's saved data is its amount as a Decimal, while Clickables store a "state" which can be a number or string, but not Decimal, array, or object). Buyables have a number of extra features which you can see on their page. Clickables also have a smaller default size.

    Useful functions for dealing with achievements and implementing their effects:

    • getClickableState(layer, id): get the state of the clickable the player has
    • setClickableState(layer, id, state): set the state of the buyable the player has
    • clickableEffect(layer, id): Returns the current effects of the clickable, if any.

    Clickables should be formatted like this:

    js
    clickables: {
    +    
    Skip to content

    Clickables

    Clickables are any kind of thing that you can click for an effect. They're a more generalized version of Buyables.

    DO NOT USE THESE TO MAKE THINGS THAT YOU CLICK REPEATEDLY FOR A BONUS BECAUSE THOSE ARE AWFUL.

    There are several differences between the two. One is that a buyable's saved data is its amount as a Decimal, while Clickables store a "state" which can be a number or string, but not Decimal, array, or object). Buyables have a number of extra features which you can see on their page. Clickables also have a smaller default size.

    Useful functions for dealing with achievements and implementing their effects:

    • getClickableState(layer, id): get the state of the clickable the player has
    • setClickableState(layer, id, state): set the state of the buyable the player has
    • clickableEffect(layer, id): Returns the current effects of the clickable, if any.

    Clickables should be formatted like this:

    js
    clickables: {
         rows: # of rows,
         cols: # of columns,
         11: {
    @@ -58,8 +58,8 @@
             etc
         }
         etc
    -}

    Features:

    • title: optional. displayed at the top in a larger font. It can also be a function that returns updating text.

    • effect(): optional. A function that calculates and returns the current values of bonuses of this clickable. Can return a value or an object containing multiple values.

    • display(): A function returning everything that should be displayed on the clickable after the title, likely changing based on its state. Can use basic HTML.

    • unlocked(): optional. A function returning a bool to determine if the clickable is visible or not. Default is unlocked.

    • canClick(): A function returning a bool to determine if you can click the clickable.

    • onClick(): A function that implements clicking one of the clickable.

    • style: optional. Applies CSS to this clickable, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the clickable was stored under, for convenient access. The clickable in the example's id is 11.

    You can also use these features on the clickables object to add a button above all the clickables, for implementing a respec button or similar.

    • masterButtonPress(): optional. If present, an additional button will appear above the clickables. Pressing it will call this function.

    • masterButtonText: optional. Text to display on the Master Button.

    • showMasterButton(): optional. A function determining whether or not to show the button. Defaults to true if absent.

    - +}

    Features:

    • title: optional. displayed at the top in a larger font. It can also be a function that returns updating text.

    • effect(): optional. A function that calculates and returns the current values of bonuses of this clickable. Can return a value or an object containing multiple values.

    • display(): A function returning everything that should be displayed on the clickable after the title, likely changing based on its state. Can use basic HTML.

    • unlocked(): optional. A function returning a bool to determine if the clickable is visible or not. Default is unlocked.

    • canClick(): A function returning a bool to determine if you can click the clickable.

    • onClick(): A function that implements clicking one of the clickable.

    • style: optional. Applies CSS to this clickable, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the clickable was stored under, for convenient access. The clickable in the example's id is 11.

    You can also use these features on the clickables object to add a button above all the clickables, for implementing a respec button or similar.

    • masterButtonPress(): optional. If present, an additional button will appear above the clickables. Pressing it will call this function.

    • masterButtonText: optional. Text to display on the Master Button.

    • showMasterButton(): optional. A function determining whether or not to show the button. Defaults to true if absent.

    + \ No newline at end of file diff --git a/public/lit/docs/custom-tab-layouts.html b/public/lit/docs/custom-tab-layouts.html index 240bd63c1..d11a0d5ed 100644 --- a/public/lit/docs/custom-tab-layouts.html +++ b/public/lit/docs/custom-tab-layouts.html @@ -6,12 +6,12 @@ Custom tab layouts | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
    Skip to content

    Custom tab layouts

    Note: If you are using subtabs, tabFormat is used differently, but you still use the same format within each subtabs. See here for more on subtabs.

    Custom tab layouts can be used to do basically anything in a tab window, especially combined with the "style" layer feature. The tabFormat feature is an array of things, like this:

    js
    tabFormat: [
    +    
    Skip to content

    Custom tab layouts

    Note: If you are using subtabs, tabFormat is used differently, but you still use the same format within each subtabs. See here for more on subtabs.

    Custom tab layouts can be used to do basically anything in a tab window, especially combined with the "style" layer feature. The tabFormat feature is an array of things, like this:

    js
    tabFormat: [
         "main-display",
         ["prestige-button", function() { return "Melt your points into " }],
         "blank",
    @@ -63,8 +63,8 @@
         "blank",
         "blank",
         "upgrades"
    -]

    It is a list of components, which can be either just a name, or an array with arguments. If it's an array, the first item is the name of the component, the second is the data passed into it, and the third (optional) applies a CSS style to it with a "CSS object", where the keys are CSS attributes.

    These are the existing components, but you can create more in components.js:

    • display-text: Displays some text (can use basic HTML). The argument is the text to display. It can also be a function that returns updating text.

    • raw-html: Displays some basic HTML, can also be a function.

    • blank: Adds empty space. The default dimensions are 8px x 17px. The argument changes the dimensions. If it's a single value (e.g. "20px"), that determines the height. If you have a pair of arguments, the first is width and the second is height.

    • row: Display a list of components horizontally. The argument is an array of components in the tab layout format.

    • column: Display a list of components vertically. The argument is an array of components in the tab layout format. This is useful to display columns within a row.

    • main-display: The text that displays the main currency for the layer and its effects.

    • resource-display: The text that displays the currency that this layer is based on, as well as the best and/or total values for this layer's prestige currency (if they are put in startData for this layer).

    • prestige-button: The argument is a string that the prestige button should say before the amount of currency you will gain. It can also be a function that returns updating text.

    • upgrades: The layer's upgrades. The argument is optional, and is a the list of rows this component should include, if it doesn't have all of them.

    • milestones, challenges, achievements: Display the upgrades, milestones, and challenges for a layer, as appropriate.

    • buyables, clickables: Display all of the buyables/clickables for this layer, as appropriate. The argument is optional and is the size of the boxes in pixels.

    • microtabs: Display a set of subtabs for an area. The argument is the name of the set of microtabs in the "microtabs" feature.

    • bar: Display a bar. The argument is the id of the bar to display.

    • infobox: Display an infobox. The argument is the id of the infobox to display.

    • tree: Displays a tree. The argument is an array of arrays containing the names of the nodes in the tree (first by row, then by column) See here for more information on tree layouts and nodes!

    • toggle: A toggle button that toggles a bool value. The data is a pair that identifies what bool to toggle, e.g. [layer, id]

    The rest of the components are sub-components. They can be used just like other components, but are typically part of another component.

    • upgrade, milestone, challenge, buyable, clickable, achievement: An individual upgrade, challenge, etc. The argument is the id. This can be used if you want to have upgrades split up across multiple subtabs, for example.

    • respec-button, master-button: The respec and master buttons for buyables and clickables, respectively.

    • sell-one, sell-all: The "sell one" and "sell all" for buyables, respectively. The argument is the id of the buyable.

    - +]

    It is a list of components, which can be either just a name, or an array with arguments. If it's an array, the first item is the name of the component, the second is the data passed into it, and the third (optional) applies a CSS style to it with a "CSS object", where the keys are CSS attributes.

    These are the existing components, but you can create more in components.js:

    • display-text: Displays some text (can use basic HTML). The argument is the text to display. It can also be a function that returns updating text.

    • raw-html: Displays some basic HTML, can also be a function.

    • blank: Adds empty space. The default dimensions are 8px x 17px. The argument changes the dimensions. If it's a single value (e.g. "20px"), that determines the height. If you have a pair of arguments, the first is width and the second is height.

    • row: Display a list of components horizontally. The argument is an array of components in the tab layout format.

    • column: Display a list of components vertically. The argument is an array of components in the tab layout format. This is useful to display columns within a row.

    • main-display: The text that displays the main currency for the layer and its effects.

    • resource-display: The text that displays the currency that this layer is based on, as well as the best and/or total values for this layer's prestige currency (if they are put in startData for this layer).

    • prestige-button: The argument is a string that the prestige button should say before the amount of currency you will gain. It can also be a function that returns updating text.

    • upgrades: The layer's upgrades. The argument is optional, and is a the list of rows this component should include, if it doesn't have all of them.

    • milestones, challenges, achievements: Display the upgrades, milestones, and challenges for a layer, as appropriate.

    • buyables, clickables: Display all of the buyables/clickables for this layer, as appropriate. The argument is optional and is the size of the boxes in pixels.

    • microtabs: Display a set of subtabs for an area. The argument is the name of the set of microtabs in the "microtabs" feature.

    • bar: Display a bar. The argument is the id of the bar to display.

    • infobox: Display an infobox. The argument is the id of the infobox to display.

    • tree: Displays a tree. The argument is an array of arrays containing the names of the nodes in the tree (first by row, then by column) See here for more information on tree layouts and nodes!

    • toggle: A toggle button that toggles a bool value. The data is a pair that identifies what bool to toggle, e.g. [layer, id]

    The rest of the components are sub-components. They can be used just like other components, but are typically part of another component.

    • upgrade, milestone, challenge, buyable, clickable, achievement: An individual upgrade, challenge, etc. The argument is the id. This can be used if you want to have upgrades split up across multiple subtabs, for example.

    • respec-button, master-button: The respec and master buttons for buyables and clickables, respectively.

    • sell-one, sell-all: The "sell one" and "sell all" for buyables, respectively. The argument is the id of the buyable.

    + \ No newline at end of file diff --git a/public/lit/docs/getting-started.html b/public/lit/docs/getting-started.html index 80777a9d6..859197b7b 100644 --- a/public/lit/docs/getting-started.html +++ b/public/lit/docs/getting-started.html @@ -6,12 +6,12 @@ Getting started | The Paper Pilot - + - + - + @@ -50,8 +50,8 @@ -
    Skip to content

    Getting started

    Welcome to The Modding Tree!

    Using the Modding Tree, at its simplest level, just requires getting a copy of it onto your computer. However, if you do it the right way, it will help in many ways.

    Don't let the word "Github" scare you away. It's actually much easier to use than most people think, especially because most people use it the hard way. The key is Github Desktop, which lets you do everything you need to, without even touching the command line.

    The benefits of using Github:

    • It makes it much, much easier to update The Modding Tree.
    • You can share your work without any extra effort using githack, or with a bit more effort, set up a github.io site.
    • It lets you undo changes to your code, and to have multiple versions of it.
    • It lets you collaborate with other people, if you want to.

    Getting set up with Github Desktop, Visual Studio Code, and The Modding Tree:

    1. Install Github Desktop and Visual Studio Code.

    2. Make a Github account. You can handle this on your own.

    3. Log in on your browser, and go back to The Modding Tree page. At the top right, there should be a button that says "fork". Click on it, and then on your username. You now have your own fork, or copy, of The Modding Tree.

    4. Open Github Desktop and log in. Ignore everything else and choose "clone a repository". A "repository" is basically a "Github project", like The Modding Tree. "Cloning" is downloading a copy of the repository to your computer.

    5. Look for The Modding Tree in the list of repositiories (it should be the only one) and click "clone".

    6. Select that you're using it for your own purposes, and click continue. It will download the files and handle everything.

    Using your repository

    1. Click on "show in explorer/finder" to the right, and then open the index.html file in the folder. The page should open up on your browser. This will let you view and test your project locally!

    2. To edit your project, click "open in VSCode" in Github Desktop.

    3. Open mod.js in VSCode, and look at the top part where it has a "modInfo" object. Fill in your mod's name to whatever you want, and change the id as well. (It can be any string value, and it's used to determine where the savefile is. Make it something that's probably unique, and don't change it again later or else it'll effectively wipe existing saves)

    4. Save mod.js, and then reload index.html in your browser. The title on the tab, as well as on the info page, will now be updated! You can reload the page every time you change the code to test it quickly and easily.

    5. Go back to Github Desktop. It's time to save your changes into the git system by making a "commit". This basically saves your work and creates a snapshot of what your code looks like at this moment, allowing you to look back at it later.

    6. At the bottom right corner, add a summary of your changes, and then click "commit to master".

    7. Finally, at the top middle, click "push origin" to push your changes out onto the online repository.

    8. You can view your project on line, or share it with others, by going to https://raw.githack.com/[YOUR-GITHUB-USERNAME]/The-Modding-Tree/master/index.html

    And now, you have successfully used Github! You can look at the documentation to see how The Modding Tree's system works and to make your mod a reality.

    - +
    Skip to content

    Getting started

    Welcome to The Modding Tree!

    Using the Modding Tree, at its simplest level, just requires getting a copy of it onto your computer. However, if you do it the right way, it will help in many ways.

    Don't let the word "Github" scare you away. It's actually much easier to use than most people think, especially because most people use it the hard way. The key is Github Desktop, which lets you do everything you need to, without even touching the command line.

    The benefits of using Github:

    • It makes it much, much easier to update The Modding Tree.
    • You can share your work without any extra effort using githack, or with a bit more effort, set up a github.io site.
    • It lets you undo changes to your code, and to have multiple versions of it.
    • It lets you collaborate with other people, if you want to.

    Getting set up with Github Desktop, Visual Studio Code, and The Modding Tree:

    1. Install Github Desktop and Visual Studio Code.

    2. Make a Github account. You can handle this on your own.

    3. Log in on your browser, and go back to The Modding Tree page. At the top right, there should be a button that says "fork". Click on it, and then on your username. You now have your own fork, or copy, of The Modding Tree.

    4. Open Github Desktop and log in. Ignore everything else and choose "clone a repository". A "repository" is basically a "Github project", like The Modding Tree. "Cloning" is downloading a copy of the repository to your computer.

    5. Look for The Modding Tree in the list of repositiories (it should be the only one) and click "clone".

    6. Select that you're using it for your own purposes, and click continue. It will download the files and handle everything.

    Using your repository

    1. Click on "show in explorer/finder" to the right, and then open the index.html file in the folder. The page should open up on your browser. This will let you view and test your project locally!

    2. To edit your project, click "open in VSCode" in Github Desktop.

    3. Open mod.js in VSCode, and look at the top part where it has a "modInfo" object. Fill in your mod's name to whatever you want, and change the id as well. (It can be any string value, and it's used to determine where the savefile is. Make it something that's probably unique, and don't change it again later or else it'll effectively wipe existing saves)

    4. Save mod.js, and then reload index.html in your browser. The title on the tab, as well as on the info page, will now be updated! You can reload the page every time you change the code to test it quickly and easily.

    5. Go back to Github Desktop. It's time to save your changes into the git system by making a "commit". This basically saves your work and creates a snapshot of what your code looks like at this moment, allowing you to look back at it later.

    6. At the bottom right corner, add a summary of your changes, and then click "commit to master".

    7. Finally, at the top middle, click "push origin" to push your changes out onto the online repository.

    8. You can view your project on line, or share it with others, by going to https://raw.githack.com/[YOUR-GITHUB-USERNAME]/The-Modding-Tree/master/index.html

    And now, you have successfully used Github! You can look at the documentation to see how The Modding Tree's system works and to make your mod a reality.

    + \ No newline at end of file diff --git a/public/lit/docs/infoboxes.html b/public/lit/docs/infoboxes.html index 4d58a5549..bf8ccb447 100644 --- a/public/lit/docs/infoboxes.html +++ b/public/lit/docs/infoboxes.html @@ -6,12 +6,12 @@ Infoboxes | The Paper Pilot - + - + - + @@ -50,15 +50,15 @@ -
    Skip to content

    Infoboxes

    Infoboxes are good for displaying "lore", or story elements, as well as for explaining complicated things.

    In the default tab layout, the first infobox will be displayed at the very top of the tab.

    Infoboxes are defined like other Big Features:

    js
    infoboxes: {
    +    
    Skip to content

    Infoboxes

    Infoboxes are good for displaying "lore", or story elements, as well as for explaining complicated things.

    In the default tab layout, the first infobox will be displayed at the very top of the tab.

    Infoboxes are defined like other Big Features:

    js
    infoboxes: {
         lore: {
             title: "foo",
             body() { return "bar" },
             etc
         },
         etc
    -}

    Features:

    • title: The text displayed above the main box. Can be a function to be dynamic, and can use basic HTML.

    • body: The text displayed inside the box. Can be a function to be dynamic, and can use basic HTML.

    • style, titleStyle, bodyStyle: optional. Apply CSS to the infobox, or to the title button or body of the infobox, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • unlocked(): optional. A function returning a bool to determine if the infobox is visible or not. Default is unlocked.

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar

    • id: assigned automagically. It's the "key" which the bar was stored under, for convenient access. The infobox in the example's id is "lore".

    - +}

    Features:

    • title: The text displayed above the main box. Can be a function to be dynamic, and can use basic HTML.

    • body: The text displayed inside the box. Can be a function to be dynamic, and can use basic HTML.

    • style, titleStyle, bodyStyle: optional. Apply CSS to the infobox, or to the title button or body of the infobox, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • unlocked(): optional. A function returning a bool to determine if the infobox is visible or not. Default is unlocked.

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar

    • id: assigned automagically. It's the "key" which the bar was stored under, for convenient access. The infobox in the example's id is "lore".

    + \ No newline at end of file diff --git a/public/lit/docs/layer-features.html b/public/lit/docs/layer-features.html index 8eaf37104..154ae1236 100644 --- a/public/lit/docs/layer-features.html +++ b/public/lit/docs/layer-features.html @@ -6,12 +6,12 @@ Layer Features | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
    Skip to content

    Layer Features

    This is a more comprehensive list of established features to add to layers. You can add more freely, if you want to have other functions or values associated with your layer. These have special functionality, though.

    You can make almost any value dynamic by using a function in its place, including all display strings and styling/color features.

    Layer Definition features

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar to access the saved value. It makes copying code to new layers easier. It is also assigned to all upgrades and buyables and such.

    • name: optional. used in reset confirmations (and the default infobox title). If absent, it just uses the layer's id.

    • startData(): A function to return the default save data for this layer. Add any variables you have to it. Make sure to use Decimal values rather than normal numbers.

      Standard values: - Required: - unlocked: a bool determining if this layer is unlocked or not - points: a Decimal, the main currency for the layer - Optional: - total: A Decimal, tracks total amount of main prestige currency. Always tracked, but only shown if you add it here. - best: A Decimal, tracks highest amount of main prestige currency. Always tracked, but only shown if you add it here. - unlockOrder: used to keep track of relevant layers unlocked before this one. - resetTime: A number, time since this layer was last prestiged (or reset by another layer)

    • color: A color associated with this layer, used in many places. (A string in hex format with a #)

    • row: The row of the layer, starting at 0. This affects where the node appears on the standard tree, and which resets affect the layer.

      Using "side" instead of a number will cause the layer to appear off to the side as a smaller node (useful for achievements and statistics). Side layers are not affected by resets unless you add a doReset to them.

    • displayRow: OVERRIDE Changes where the layer node appears without changing where it is in the reset order.

    • resource: Name of the main currency you gain by resetting on this layer.

    • effect(): optional. A function that calculates and returns the current values of any bonuses inherent to the main currency. Can return a value or an object containing multiple values. You will also have to implement the effect where it is applied.

    • effectDescription: optional. A function that returns a description of this effect. If the text stays constant, it can just be a string.

    • layerShown(): optional, A function returning a bool which determines if this layer's node should be visible on the tree. It can also return "ghost", which will hide the layer, but its node will still take up space in the tree. Defaults to true.

    • hotkeys: optional. An array containing information on any hotkeys associated with this layer:

      js
      hotkeys: [
      +    
      Skip to content

      Layer Features

      This is a more comprehensive list of established features to add to layers. You can add more freely, if you want to have other functions or values associated with your layer. These have special functionality, though.

      You can make almost any value dynamic by using a function in its place, including all display strings and styling/color features.

      Layer Definition features

      • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar to access the saved value. It makes copying code to new layers easier. It is also assigned to all upgrades and buyables and such.

      • name: optional. used in reset confirmations (and the default infobox title). If absent, it just uses the layer's id.

      • startData(): A function to return the default save data for this layer. Add any variables you have to it. Make sure to use Decimal values rather than normal numbers.

        Standard values: - Required: - unlocked: a bool determining if this layer is unlocked or not - points: a Decimal, the main currency for the layer - Optional: - total: A Decimal, tracks total amount of main prestige currency. Always tracked, but only shown if you add it here. - best: A Decimal, tracks highest amount of main prestige currency. Always tracked, but only shown if you add it here. - unlockOrder: used to keep track of relevant layers unlocked before this one. - resetTime: A number, time since this layer was last prestiged (or reset by another layer)

      • color: A color associated with this layer, used in many places. (A string in hex format with a #)

      • row: The row of the layer, starting at 0. This affects where the node appears on the standard tree, and which resets affect the layer.

        Using "side" instead of a number will cause the layer to appear off to the side as a smaller node (useful for achievements and statistics). Side layers are not affected by resets unless you add a doReset to them.

      • displayRow: OVERRIDE Changes where the layer node appears without changing where it is in the reset order.

      • resource: Name of the main currency you gain by resetting on this layer.

      • effect(): optional. A function that calculates and returns the current values of any bonuses inherent to the main currency. Can return a value or an object containing multiple values. You will also have to implement the effect where it is applied.

      • effectDescription: optional. A function that returns a description of this effect. If the text stays constant, it can just be a string.

      • layerShown(): optional, A function returning a bool which determines if this layer's node should be visible on the tree. It can also return "ghost", which will hide the layer, but its node will still take up space in the tree. Defaults to true.

      • hotkeys: optional. An array containing information on any hotkeys associated with this layer:

        js
        hotkeys: [
             {
                 key: "p", // What the hotkey button is. Use uppercase if it's combined with shift, or "ctrl+x" for holding down ctrl.
                 description: "p: reset your points for prestige points", // The description of the hotkey that is displayed in the game's How To Play tab
        @@ -59,8 +59,8 @@
         ]
      • style: optional. a "CSS object" where the keys are CSS attributes, containing any CSS that should affect this layer's entire tab.

      • tabFormat: optional. use this if you want to add extra things to your tab or change the layout. See here for more info.

      • midsection: optional, an alternative to tabFormat, which is inserted in between Milestones and Buyables in the standard tab layout. (cannot do subtabs)

      Big features (all optional)

      • upgrades: A grid of one-time purchases which can have unique upgrade conditions, currency costs, and bonuses. See here for more info.

      • milestones: A list of bonuses gained upon reaching certain thresholds of a resource. Often used for automation/QOL. See here for more info.

      • challenges: The player can enter challenges, which make the game harder. If they reach a goal and beat the challenge, they recieve a bonus. See here for more info.

      • buyables: Effectively upgrades that can be bought multiple times, and are optionally respeccable. Many uses. See here for more info.

      • clickables: Extremely versatile and generalized buttons which can only be clicked sometimes. See here for more info.

      • microtabs: An area that functions like a set of subtabs, with buttons at the top changing the content within. (Advanced) See here for more info.

      • bars: Display some information as a progress bar, gague, or similar. They are highly customizable, and can be vertical as well. See here for more info.

      • achievements: Kind of like milestones, but with a different display style and some other differences. Extra features are on the way at a later date! See here for more info.

      • infoboxes: Displays some text in a box that can be shown or hidden. See here for more info.

      • achievementPopups, milestonePopups: optional, If false, disables popup message when you get the achievement/milestone. True by default.

      Prestige formula features

      • type: optional. Determines which prestige formula you use. Defaults to "none".

        • "normal": The amount of currency you gain is independent of its current amount (like Prestige). The formula before bonuses is based on baseResource^exponent
        • "static": The cost is dependent on your total after reset. The formula before bonuses is based on base^(x^exponent)
        • "custom": You can define everything, from the calculations to the text on the button, yourself. (See more at the bottom)
        • "none": This layer does not prestige, and therefore does not need any of the other features in this section.
      • baseResource: The name of the resource that determines how much of the main currency you gain on reset.

      • baseAmount(): A function that gets the current value of the base resource.

      • requires: A Decimal, the amount of the base needed to gain 1 of the prestige currency. Also the amount required to unlock the layer. You can instead make this a function, to make it harder if another layer was unlocked first (based on unlockOrder).

      • exponent: Used as described above.

      • base: sometimes required. required for "static" layers, used as described above. If absent, defaults to 2. Must be greater than 1.

      • roundUpCost: optional. a bool, which is true if the resource cost needs to be rounded up. (use if the base resource is a "static" currency.)

      • gainMult(), gainExp(): optional. Functions that calculate the multiplier and exponent on resource gain from upgrades and boosts and such. Plug in any bonuses here.

      • softcap, softcapPower: optional. For normal layers, gain beyond [softcap] points is put to the [softcapPower]th power Default for softcap is e1e7, and for power is 0.5.

      • canBuyMax(): sometimes required. required for static layers, function used to determine if buying max is permitted.

      • onPrestige(gain): optional. A function that triggers when this layer prestiges, just before you gain the currency. Can be used to have secondary resource gain on prestige, or to recalculate things or whatnot.

      • resetDescription: optional. Use this to replace "Reset for " on the Prestige button with something else.

      • prestigeButtonText(): sometimes required. Use this to make the entirety of the text a Prestige button contains. Only required for custom layers, but usable by all types.

      • passiveGeneration(): optional, returns a regular number. You automatically generate your gain times this number every second (does nothing if absent) This is good for automating Normal layers.

      • autoPrestige(): optional, returns a boolean, if true, the layer will always automatically do a prestige if it can. This is good for automating Static layers.

      Tree/node features

      • symbol: optional. The text that appears on this layer's node. Default is the layer id with the first letter capitalized.

      • image: override. The url (local or global) of an image that goes on the node. (Overrides symbol)

      • position: optional. Determines the horizontal position of the layer in its row in a standard tree. By default, it uses the layer id, and layers are sorted in alphabetical order.

      • branches: optional. An array of layer/node ids. On a tree, a line will appear from this layer to all of the layers in the list. Alternatively, an entry in the array can be a 2-element array consisting of the layer id and a color value. The color value can either be a string with a hex color code, or a number from 1-3 (theme-affected colors).

      • nodeStyle: optional. A CSS object, where the keys are CSS attributes, which styles this layer's node on the tree.

      • tooltip() / tooltipLocked(): optional. Functions that return text, which is the tooltip for the node when the layer is unlocked or locked, respectively. By default the tooltips behave the same as in the original Prestige Tree. If the value is "", the tooltip will be disabled.

      Other features

      • doReset(resettingLayer): optional. Is triggered when a layer on a row greater than or equal to this one does a reset. The default behavior is to reset everything on the row, but only if it was triggered by a layer in a higher row. doReset is always called for side layers, but for these the default behavior is to reset nothing.

        If you want to keep things, determine what to keep based on resettingLayer, milestones, and such, then call layerDataReset(layer, keep), where layer is this layer, and keep is an array of the names of things to keep. It can include things like "points", "best", "total" (for this layer's prestige currency), "upgrades", any unique variables like "generatorPower", etc. If you want to only keep specific upgrades or something like that, save them in a separate variable, then call layerDataReset, and then set player[this.layer].upgrades to the saved upgrades.

      • update(diff): optional. This function is called every game tick. Use it for any passive resource production or time-based things. diff is the time since the last tick.

      • autoUpgrade: optional, a boolean value, if true, the game will attempt to buy this layer's upgrades every tick. Defaults to false.

      • automate(): optional. This function is called every game tick, after production. Use it to activate automation things that aren't otherwise supported.

      • resetsNothing: optional. Returns true if this layer shouldn't trigger any resets when you prestige.

      • increaseUnlockOrder: optional. An array of layer ids. When this layer is unlocked for the first time, the unlockOrder value for any not-yet-unlocked layers in this list increases. This can be used to make them harder to unlock.

      • shouldNotify: optional. A function to return true if this layer should be highlighted in the tree. The layer will automatically be highlighted if you can buy an upgrade whether you have this or not.

      • componentStyles: optional. An object that contains a set of functions returning CSS objects. Each of these will be applied to any components on the layer with the type of its id. Example:

      js
      componentStyles: {
           "challenge"() { return {'height': '200px'} },
           "prestige-button"() { return {'color': '#AA66AA'} }
      -}

      Custom Prestige type

      (All of these can also be used by other prestige types)

      • getResetGain(): mostly for custom prestige type. Returns how many points you should get if you reset now. You can call getResetGain(this.layer, useType = "static") or similar to calculate what your gain would be under another prestige type (provided you have all of the required features in the layer).

      • getNextAt(canMax=false): mostly for custom prestige type. Returns how many of the base currency you need to get to the next point. canMax is an optional variable used with Static-ish layers to differentiate between if it's looking for the first point you can reset at, or the requirement for any gain at all (Supporting both is good). You can also call getNextAt(this.layer, canMax=false, useType = "static") or similar to calculate what your next at would be under another prestige type (provided you have all of the required features in the layer).

      • canReset(): mostly for custom prestige type. Return true only if you have the resources required to do a prestige here.

      • prestigeNotify(): mostly for custom prestige types, returns true if this layer should be subtly highlighted to indicate you can prestige for a meaningful gain.

      - +}

      Custom Prestige type

      (All of these can also be used by other prestige types)

      • getResetGain(): mostly for custom prestige type. Returns how many points you should get if you reset now. You can call getResetGain(this.layer, useType = "static") or similar to calculate what your gain would be under another prestige type (provided you have all of the required features in the layer).

      • getNextAt(canMax=false): mostly for custom prestige type. Returns how many of the base currency you need to get to the next point. canMax is an optional variable used with Static-ish layers to differentiate between if it's looking for the first point you can reset at, or the requirement for any gain at all (Supporting both is good). You can also call getNextAt(this.layer, canMax=false, useType = "static") or similar to calculate what your next at would be under another prestige type (provided you have all of the required features in the layer).

      • canReset(): mostly for custom prestige type. Return true only if you have the resources required to do a prestige here.

      • prestigeNotify(): mostly for custom prestige types, returns true if this layer should be subtly highlighted to indicate you can prestige for a meaningful gain.

    + \ No newline at end of file diff --git a/public/lit/docs/main-mod-info.html b/public/lit/docs/main-mod-info.html index 47aa382f8..6692beacd 100644 --- a/public/lit/docs/main-mod-info.html +++ b/public/lit/docs/main-mod-info.html @@ -6,12 +6,12 @@ mod.js | The Paper Pilot - + - + - + @@ -50,12 +50,12 @@ -
    Skip to content

    mod.js

    All of the non-layer code and data that you're likely to edit is here in mod.js! Everything in mod.js will not be altered by updates, besides the addition of new things.

    Here's a breakdown of what's in it:

    • modInfo is where most of the basic configuration for the mod is. It contains:

      • name: The name of your mod. (a string)

      • id: The id for your mod, a unique string that is used to determine savefile location. Setting it is important!

      • author: The name of the author, displayed in the info tab.

      • pointsName: This changes what is displayed instead of "points" for the main currency. (It does not affect it in the code.)

      • discordName, discordLink: If you have a Discord server or other discussion place, you can add a link to it.

        "discordName" is the text on the link, and "discordLink" is the url of an invite. If you're using a Discord invite, please make sure it's set to never expire.

      • offlineLimit: The maximum amount of offline time that the player can accumulate, in hours. Any extra time is lost. (a number)

        This is useful because most of these mods are fast-paced enough that too much offline time ruins the balance, such as the time in between updates. That is why I suggest developers disable offline time on their own savefile.

      • initialStartPoints: A Decimal for the amount of points a new player should start with.

    • VERSION is used to describe the current version of your mod. It contains:

      • num: The mod's version number, displayed at the top right of the tree tab.
      • name: The version's name, displayed alongside the number in the info tab.
    • changelog is the HTML displayed in the changelog tab.

    • doNotCallTheseFunctionsEveryTick is very important. TMT calls every function anywhere in "layers" every tick to store the result, unless specifically told not to. Functions that have are used to do an action need to be identified. "Official" functions (those in the documentation) are all fine, but if you make any new ones, add their names to this array.

    js
    // (The ones here are examples, all official functions are already taken care of)
    +    
    Skip to content

    mod.js

    All of the non-layer code and data that you're likely to edit is here in mod.js! Everything in mod.js will not be altered by updates, besides the addition of new things.

    Here's a breakdown of what's in it:

    • modInfo is where most of the basic configuration for the mod is. It contains:

      • name: The name of your mod. (a string)

      • id: The id for your mod, a unique string that is used to determine savefile location. Setting it is important!

      • author: The name of the author, displayed in the info tab.

      • pointsName: This changes what is displayed instead of "points" for the main currency. (It does not affect it in the code.)

      • discordName, discordLink: If you have a Discord server or other discussion place, you can add a link to it.

        "discordName" is the text on the link, and "discordLink" is the url of an invite. If you're using a Discord invite, please make sure it's set to never expire.

      • offlineLimit: The maximum amount of offline time that the player can accumulate, in hours. Any extra time is lost. (a number)

        This is useful because most of these mods are fast-paced enough that too much offline time ruins the balance, such as the time in between updates. That is why I suggest developers disable offline time on their own savefile.

      • initialStartPoints: A Decimal for the amount of points a new player should start with.

    • VERSION is used to describe the current version of your mod. It contains:

      • num: The mod's version number, displayed at the top right of the tree tab.
      • name: The version's name, displayed alongside the number in the info tab.
    • changelog is the HTML displayed in the changelog tab.

    • doNotCallTheseFunctionsEveryTick is very important. TMT calls every function anywhere in "layers" every tick to store the result, unless specifically told not to. Functions that have are used to do an action need to be identified. "Official" functions (those in the documentation) are all fine, but if you make any new ones, add their names to this array.

    js
    // (The ones here are examples, all official functions are already taken care of)
     var doNotCallTheseFunctionsEveryTick = ["doReset", "buy", "onPurchase", "blowUpEverything"]
    • getStartPoints(): A function to determine the amount of points the player starts with after a reset. (returns a Decimal value)

    • canGenPoints(): A function returning a boolean for if points should be generated. Use this if you want an upgrade to unlock generating points.

    • getPointGen(): A function that calculates your points per second. Anything that affects your point gain should go into the calculation here.

    • addedPlayerData(): A function that returns any non-layer-related data that you want to be added to the save data and "player" object.

    js
    function addedPlayerData() { return {
     	weather: "Yes",
     	happiness: new Decimal(72),
    -}}
    • displayThings: An array of functions used to display extra things at the top of the tree tab. Each function returns a string, which is a line to display (with basic HTML support). If a function returns nothing, nothing is displayed (and it doesn't take up a line).

    • isEndgame(): A function to determine if the player has reached the end of the game, at which point the "you win!" screen appears.

    Less important things beyond this point!

    • maxTickLength(): Returns the maximum tick length, in milliseconds. Only really useful if you have something that reduces over time, which long ticks mess up (usually a challenge).
    - +}}
    • displayThings: An array of functions used to display extra things at the top of the tree tab. Each function returns a string, which is a line to display (with basic HTML support). If a function returns nothing, nothing is displayed (and it doesn't take up a line).

    • isEndgame(): A function to determine if the player has reached the end of the game, at which point the "you win!" screen appears.

    Less important things beyond this point!

    • maxTickLength(): Returns the maximum tick length, in milliseconds. Only really useful if you have something that reduces over time, which long ticks mess up (usually a challenge).
    + \ No newline at end of file diff --git a/public/lit/docs/milestones.html b/public/lit/docs/milestones.html index af8207214..adf4d659f 100644 --- a/public/lit/docs/milestones.html +++ b/public/lit/docs/milestones.html @@ -6,12 +6,12 @@ Milestones | The Paper Pilot - + - + - + @@ -50,15 +50,15 @@ -
    Skip to content

    Milestones

    Milestones are awarded to the player when they meet a certain goal, and give some benefit. Milestones should be formatted like this:

    js
    milestones: {
    +    
    Skip to content

    Milestones

    Milestones are awarded to the player when they meet a certain goal, and give some benefit. Milestones should be formatted like this:

    js
    milestones: {
         0: {
             requirementDescription: "123 waffles",
             effectDescription: "blah",
             done() { return player.w.points.gte(123) }
         }
         etc
    -}

    You can use hasMilestone(layer, id) to determine if the player has a given milestone

    Milestone features:

    • requirementDescription: A string describing the requirement for unlocking this milestone. Suggestion: Use a "total". It can also be a function that returns updating text. Can use basic HTML.

    • effectDescription: A string describing the reward for having the milestone. You will have to implement the reward elsewhere. It can also be a function that returns updating text. Can use basic HTML.

    • done(): A function returning a boolean to determine if the milestone should be awarded.

    • toggles: optional. Creates toggle buttons that appear on the milestone when it is unlocked. The toggles can toggle a given boolean value in a layer. It is defined as an array of paired items, one pair per toggle. The first is the internal name of the layer the value being toggled is stored in, and the second is the internal name of the variable to toggle. (e.g. [["b", "auto"], ["g", "auto"])

      Tip: Toggles are not de-set if the milestone becomes locked! In this case, you should also check if the player has the milestone.

    • style: optional. Applies CSS to this milestone, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • unlocked(): optional. A function returning a boolean to determine if the milestone should be shown. If absent, it is always shown.

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the milestone was stored under, for convenient access. The milestone in the example's id is 0.

    Disaable milestone popups by adding milestonePopups: false to the layer.

    - +}

    You can use hasMilestone(layer, id) to determine if the player has a given milestone

    Milestone features:

    • requirementDescription: A string describing the requirement for unlocking this milestone. Suggestion: Use a "total". It can also be a function that returns updating text. Can use basic HTML.

    • effectDescription: A string describing the reward for having the milestone. You will have to implement the reward elsewhere. It can also be a function that returns updating text. Can use basic HTML.

    • done(): A function returning a boolean to determine if the milestone should be awarded.

    • toggles: optional. Creates toggle buttons that appear on the milestone when it is unlocked. The toggles can toggle a given boolean value in a layer. It is defined as an array of paired items, one pair per toggle. The first is the internal name of the layer the value being toggled is stored in, and the second is the internal name of the variable to toggle. (e.g. [["b", "auto"], ["g", "auto"])

      Tip: Toggles are not de-set if the milestone becomes locked! In this case, you should also check if the player has the milestone.

    • style: optional. Applies CSS to this milestone, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • unlocked(): optional. A function returning a boolean to determine if the milestone should be shown. If absent, it is always shown.

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the milestone was stored under, for convenient access. The milestone in the example's id is 0.

    Disaable milestone popups by adding milestonePopups: false to the layer.

    + \ No newline at end of file diff --git a/public/lit/docs/subtabs-and-microtabs.html b/public/lit/docs/subtabs-and-microtabs.html index b29a5e4a3..aeb51ee47 100644 --- a/public/lit/docs/subtabs-and-microtabs.html +++ b/public/lit/docs/subtabs-and-microtabs.html @@ -6,12 +6,12 @@ Subtabs and Microtabs | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
    Skip to content

    Subtabs and Microtabs

    Subtabs are separate sections of a tab that you can view by selecting one at the top of the tab. Microtabs are smaller areas that function in much the same way. You can also embed layers inside of subtabs/microtabs.

    Subtabs are defined by using the tab format like this, where each element of tabFormat is given the name of that subtab:

    js
    tabFormat: {
    +    
    Skip to content

    Subtabs and Microtabs

    Subtabs are separate sections of a tab that you can view by selecting one at the top of the tab. Microtabs are smaller areas that function in much the same way. You can also embed layers inside of subtabs/microtabs.

    Subtabs are defined by using the tab format like this, where each element of tabFormat is given the name of that subtab:

    js
    tabFormat: {
         "Main tab": {
             content: [tab format things],
             *subtab features*
    @@ -74,8 +74,8 @@
         otherStuff: {
             // There could be another set of microtabs here
         }
    -}

    Normal subtabs and microtab subtabs both use the same features:

    Features:

    • content: The tab layout code for the subtab, in the tab layout format.

    • style: optional. Applies CSS to the whole subtab when switched to, in the form of an "CSS Object", where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • buttonStyle: optional. A CSS object, which affects the appearance of the button for that subtab.

    • unlocked(): optional. a function to determine if the button for this subtab should be visible. By default, a subtab is always unlocked. You can't use the "this" keyword in this function.

    • shouldNotify(): optional, if true, the tab button will be highlighted to notify the player that there is something there.

    • embedLayer: SIGNIFICANT, the id of another layer. If you have this, it will override "content", "style" and "shouldNotify", instead displaying the entire layer in the subtab.

    - +}

    Normal subtabs and microtab subtabs both use the same features:

    Features:

    • content: The tab layout code for the subtab, in the tab layout format.

    • style: optional. Applies CSS to the whole subtab when switched to, in the form of an "CSS Object", where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • buttonStyle: optional. A CSS object, which affects the appearance of the button for that subtab.

    • unlocked(): optional. a function to determine if the button for this subtab should be visible. By default, a subtab is always unlocked. You can't use the "this" keyword in this function.

    • shouldNotify(): optional, if true, the tab button will be highlighted to notify the player that there is something there.

    • embedLayer: SIGNIFICANT, the id of another layer. If you have this, it will override "content", "style" and "shouldNotify", instead displaying the entire layer in the subtab.

    + \ No newline at end of file diff --git a/public/lit/docs/trees-and-tree-customization.html b/public/lit/docs/trees-and-tree-customization.html index ba0922c14..2d235eb7c 100644 --- a/public/lit/docs/trees-and-tree-customization.html +++ b/public/lit/docs/trees-and-tree-customization.html @@ -6,12 +6,12 @@ Trees and tree customization | The Paper Pilot - + - + - + @@ -50,10 +50,10 @@ -
    Skip to content

    Trees and tree customization

    If you want to have something beyond the standard tree on the left tab, you can do that in tree.js. You can change the layout of the tree, including making non-layer nodes, change it into something other than a tree, or hide the left tab altogether. This also introduces the "tree" component, which can be used in your layers as well.

    layoutInfo

    The most important part is layoutInfo, containing:

    • startTab: The id of the default tab to show on the left at the start.
    • showTree: True if the tree tab should be shown at the start of the game. (The other tab will fill the whole page)
    • treeLayout: If present, overrides the tree layout and places nodes as you describe instead (explained in the next section).

    Additionally, if you want the main layout to not be a tree, you can edit the "tree-tab" layer at the bottom of tree.js to modify it just like a normal layer's tab. You can even switch between left tabs, using showNavTab(layer) to make that layer appear on the left.

    Trees

    The tree component is defined as an array of arrays of names of layers or nodes to show in the tree. They work just like layers/ nodes in the main tree (but branches between nodes will only work on the first node if you have duplicates.)

    Here is an example tree:

    js
    [["p"],
    +    
    Skip to content

    Trees and tree customization

    If you want to have something beyond the standard tree on the left tab, you can do that in tree.js. You can change the layout of the tree, including making non-layer nodes, change it into something other than a tree, or hide the left tab altogether. This also introduces the "tree" component, which can be used in your layers as well.

    layoutInfo

    The most important part is layoutInfo, containing:

    • startTab: The id of the default tab to show on the left at the start.
    • showTree: True if the tree tab should be shown at the start of the game. (The other tab will fill the whole page)
    • treeLayout: If present, overrides the tree layout and places nodes as you describe instead (explained in the next section).

    Additionally, if you want the main layout to not be a tree, you can edit the "tree-tab" layer at the bottom of tree.js to modify it just like a normal layer's tab. You can even switch between left tabs, using showNavTab(layer) to make that layer appear on the left.

    Trees

    The tree component is defined as an array of arrays of names of layers or nodes to show in the tree. They work just like layers/ nodes in the main tree (but branches between nodes will only work on the first node if you have duplicates.)

    Here is an example tree:

    js
    [["p"],
      ["left", "blank", "right", "blank"]
    - ["a", "b", "blank", "c", "weirdButton"]]

    Nodes

    Nodes are non-layer buttons that can go in trees. They are defined similarly to layers, but with addNode instead of addLayer.

    Features:

    • color: optional, The node's color. (A string in hex format with a #)

    • symbol: optional The text on the button (The id capitalized by default)

    • canClick(): Returns true if the player can click the node. ()

    • onClick(): The function called when the node is clicked.

    • layerShown(): optional, A function returning a bool which determines if this node should be visible. It can also return "ghost", which will hide the layer, but its node will still take up space in its tree.

    • branches: optional. An array of layer/node ids. On a tree, a line will appear from this node to all of the nodes in the list. Alternatively, an entry in the array can be a 2-element array consisting of the id and a color value. The color value can either be a string with a hex color code, or a number from 1-3 (theme-affected colors).

    • nodeStyle: optional. A CSS object, where the keys are CSS attributes, which styles this node on the tree.

    • tooltip() / tooltipLocked(): optional. Functions that return text, which is the tooltip for the node when the layer is unlocked or locked, respectively. By default the tooltips behave the same as in the original Prestige Tree.

    • row: optional, the row that this node appears in (for the default tree).

    • position: optional, Determines the horizontal position of the layer in its row in a default tree. By default, it uses the id, and layers/nodes are sorted in alphabetical order.

    - + ["a", "b", "blank", "c", "weirdButton"]]

    Nodes

    Nodes are non-layer buttons that can go in trees. They are defined similarly to layers, but with addNode instead of addLayer.

    Features:

    • color: optional, The node's color. (A string in hex format with a #)

    • symbol: optional The text on the button (The id capitalized by default)

    • canClick(): Returns true if the player can click the node. ()

    • onClick(): The function called when the node is clicked.

    • layerShown(): optional, A function returning a bool which determines if this node should be visible. It can also return "ghost", which will hide the layer, but its node will still take up space in its tree.

    • branches: optional. An array of layer/node ids. On a tree, a line will appear from this node to all of the nodes in the list. Alternatively, an entry in the array can be a 2-element array consisting of the id and a color value. The color value can either be a string with a hex color code, or a number from 1-3 (theme-affected colors).

    • nodeStyle: optional. A CSS object, where the keys are CSS attributes, which styles this node on the tree.

    • tooltip() / tooltipLocked(): optional. Functions that return text, which is the tooltip for the node when the layer is unlocked or locked, respectively. By default the tooltips behave the same as in the original Prestige Tree.

    • row: optional, the row that this node appears in (for the default tree).

    • position: optional, Determines the horizontal position of the layer in its row in a default tree. By default, it uses the id, and layers/nodes are sorted in alphabetical order.

    + \ No newline at end of file diff --git a/public/lit/docs/updating-tmt.html b/public/lit/docs/updating-tmt.html index fbc69222e..ab68149b8 100644 --- a/public/lit/docs/updating-tmt.html +++ b/public/lit/docs/updating-tmt.html @@ -6,12 +6,12 @@ Updating The Modding Tree | The Paper Pilot - + - + - + @@ -50,8 +50,8 @@ -
    Skip to content

    Updating The Modding Tree

    This tutorial assumes that you have used the Getting Started Tutorial, and are using Github Desktop and VSCode for your mod.

    Here's what you have to do when there's a TMT update:

    1. Look at the changelog. It will warn you if the update will break anything or require any changes. Decide if you want to try to update.

    2. Open Github Desktop, and at the top middle, click "fetch origin". This will make Github Desktop get information about the update.

    3. Click where it says "current branch: master" at the top middle, and at the bottom of the thing that appears, click "choose a branch to merge into master".

    4. Select upstream/master. It will likely say there are conflicts, but you have tools to resolve them. Click "Merge upstream/master into master".

    5. A conflict happens when the things you're trying to merge have both made changes in the same place. Click "open in Visual Studio Code" next to the first file.

    6. Scroll down through the file, and look for the parts highlighted in red and green. One of these is your code, and the other is some code that will be modified by the update. Do your best to try to edit things to keep the updated changes, but keep your content.

    7. Continue to do this for all remaining changes.

    8. Do any other changes required by the update, run the game, fix issues, etc.

    - +
    Skip to content

    Updating The Modding Tree

    This tutorial assumes that you have used the Getting Started Tutorial, and are using Github Desktop and VSCode for your mod.

    Here's what you have to do when there's a TMT update:

    1. Look at the changelog. It will warn you if the update will break anything or require any changes. Decide if you want to try to update.

    2. Open Github Desktop, and at the top middle, click "fetch origin". This will make Github Desktop get information about the update.

    3. Click where it says "current branch: master" at the top middle, and at the bottom of the thing that appears, click "choose a branch to merge into master".

    4. Select upstream/master. It will likely say there are conflicts, but you have tools to resolve them. Click "Merge upstream/master into master".

    5. A conflict happens when the things you're trying to merge have both made changes in the same place. Click "open in Visual Studio Code" next to the first file.

    6. Scroll down through the file, and look for the parts highlighted in red and green. One of these is your code, and the other is some code that will be modified by the update. Do your best to try to edit things to keep the updated changes, but keep your content.

    7. Continue to do this for all remaining changes.

    8. Do any other changes required by the update, run the game, fix issues, etc.

    + \ No newline at end of file diff --git a/public/lit/docs/upgrades.html b/public/lit/docs/upgrades.html index a91048a18..6159b28b9 100644 --- a/public/lit/docs/upgrades.html +++ b/public/lit/docs/upgrades.html @@ -6,12 +6,12 @@ Upgrades | The Paper Pilot - + - + - + @@ -50,7 +50,7 @@ -
    Skip to content

    Upgrades

    Useful functions for dealing with Upgrades and implementing their effects:

    • hasUpgrade(layer, id): determine if the player has the upgrade
    • upgradeEffect(layer, id): Returns the current effects of the upgrade, if any
    • buyUpgrade(layer, id): Buys an upgrade directly (if affordable)

    Hint: Basic point gain is calculated in mod.js's "getPointGen" function.

    Upgrades are stored in the following format:

    js
    upgrades: {
    +    
    Skip to content

    Upgrades

    Useful functions for dealing with Upgrades and implementing their effects:

    • hasUpgrade(layer, id): determine if the player has the upgrade
    • upgradeEffect(layer, id): Returns the current effects of the upgrade, if any
    • buyUpgrade(layer, id): Buys an upgrade directly (if affordable)

    Hint: Basic point gain is calculated in mod.js's "getPointGen" function.

    Upgrades are stored in the following format:

    js
    upgrades: {
         rows: # of rows,
         cols: # of columns,
         11: {
    @@ -59,8 +59,8 @@
             etc
         },
         etc
    -}

    Each upgrade should have an id where the first digit is the row and the second digit is the column.

    Individual upgrades can have these features:

    • title: optional. Displayed at the top in a larger font. It can also be a function that returns updating text. Can use basic HTML.

    • description: A description of the upgrade's effect. You will also have to implement the effect where it is applied. It can also be a function that returns updating text. Can use basic HTML.

    • effect(): optional. A function that calculates and returns the current values of any bonuses from the upgrade. Can return a value or an object containing multiple values.

    • effectDisplay(): optional. A function that returns a display of the current effects of the upgrade with formatting. Default displays nothing. Can use basic HTML.

    • fullDisplay(): OVERRIDE. Overrides the other displays and descriptions, and lets you set the full text for the upgrade. Can use basic HTML.

    • cost: A Decimal for the cost of the upgrade. By default, upgrades cost the main prestige currency for the layer.

    • unlocked(): optional. A function returning a bool to determine if the upgrade is visible or not. Default is unlocked.

    • onPurchase(): optional. This function will be called when the upgrade is purchased. Good for upgrades like "makes this layer act like it was unlocked first".

    • style: optional. Applies CSS to this upgrade, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the upgrade was stored under, for convenient access. The upgrade in the example's id is 11.

    By default, upgrades use the main prestige currency for the layer. You can include these to change them (but it needs to be a Decimal):

    • currencyDisplayName: optional. The name to display for the currency for the upgrade.

    • currencyInternalName: optional. The internal name for that currency.

    • currencyLayer: optional. The internal name of the layer that currency is stored in. If it's not in a layer (like Points), omit. If it's not stored directly in a layer, instead use the next feature.

    • currencyLocation: optional. If your currency is stored in something inside a layer (e.g. a buyable's amount), you can access it this way. This is a function returning the object in "player" that contains the value (like player[this.layer].buyables)

    If you want to do something more complicated like upgrades that cost two currencies, you can override the purchase system with these (and you need to use fullDisplay as well)

    • canAfford(): OVERRIDE, a function determining if you are able to buy the upgrade

    • pay(): OVERRIDE, a function that reduces your currencies when you buy the upgrade

    - +}

    Each upgrade should have an id where the first digit is the row and the second digit is the column.

    Individual upgrades can have these features:

    • title: optional. Displayed at the top in a larger font. It can also be a function that returns updating text. Can use basic HTML.

    • description: A description of the upgrade's effect. You will also have to implement the effect where it is applied. It can also be a function that returns updating text. Can use basic HTML.

    • effect(): optional. A function that calculates and returns the current values of any bonuses from the upgrade. Can return a value or an object containing multiple values.

    • effectDisplay(): optional. A function that returns a display of the current effects of the upgrade with formatting. Default displays nothing. Can use basic HTML.

    • fullDisplay(): OVERRIDE. Overrides the other displays and descriptions, and lets you set the full text for the upgrade. Can use basic HTML.

    • cost: A Decimal for the cost of the upgrade. By default, upgrades cost the main prestige currency for the layer.

    • unlocked(): optional. A function returning a bool to determine if the upgrade is visible or not. Default is unlocked.

    • onPurchase(): optional. This function will be called when the upgrade is purchased. Good for upgrades like "makes this layer act like it was unlocked first".

    • style: optional. Applies CSS to this upgrade, in the form of an object where the keys are CSS attributes, and the values are the values for those attributes (both as strings).

    • layer: assigned automagically. It's the same value as the name of this layer, so you can do player[this.layer].points or similar.

    • id: assigned automagically. It's the "key" which the upgrade was stored under, for convenient access. The upgrade in the example's id is 11.

    By default, upgrades use the main prestige currency for the layer. You can include these to change them (but it needs to be a Decimal):

    • currencyDisplayName: optional. The name to display for the currency for the upgrade.

    • currencyInternalName: optional. The internal name for that currency.

    • currencyLayer: optional. The internal name of the layer that currency is stored in. If it's not in a layer (like Points), omit. If it's not stored directly in a layer, instead use the next feature.

    • currencyLocation: optional. If your currency is stored in something inside a layer (e.g. a buyable's amount), you can access it this way. This is a function returning the object in "player" that contains the value (like player[this.layer].buyables)

    If you want to do something more complicated like upgrades that cost two currencies, you can override the purchase system with these (and you need to use fullDisplay as well)

    • canAfford(): OVERRIDE, a function determining if you are able to buy the upgrade

    • pay(): OVERRIDE, a function that reduces your currencies when you buy the upgrade

    + \ No newline at end of file