Building on Aether
The engine is game-agnostic. Every rule you can name lives in content you write.
1 minute readEdit this page
Aether is a platform, not a game. Nothing in the engine knows what a hit point is. All game
meaning lives above it, in packages you build against the stable, semver'd @aether/sdk.
That constraint is the product: implement any ruleset without forking anything, and ship it to every Aether table.
#The three package kinds
| Kind | What it is | Ships |
|---|---|---|
system | a game's rules, one active per world | document types, sheets, initiative, automation |
module | content and features on top of a system | content packs (documents, types, sheets, assets) |
mod | a sandboxed engine extension | iframe code plus capability grants |
#A system in miniature
systems/my-system/src/index.tsTypeScript
import type { DocumentSchema } from "@aether/core";
import { defineSystem } from "@aether/sdk";
import { z } from "zod";
const character: DocumentSchema = {
type: "my.character",
label: "Character",
data: z.object({
str: z.number().int(),
hp: z.object({ value: z.number().int(), max: z.number().int() }),
}),
makeDefault: () => ({ str: 10, hp: { value: 10, max: 10 } }),
capabilities: ["actor", "effects", "linkable"],
};
export default defineSystem({
manifest: {
id: "my-system",
kind: "system",
title: "My System",
version: "0.1.0",
minSdkVersion: "0.1.0",
authors: ["you"],
compatibility: {},
},
setup() {
return {
documents: [character],
initiative: "1d20 + ${floor((str - 10) / 2)}",
};
},
});#Two references ship in-tree
systems/demo-systemis the minimal reference system.systems/dnd5e-srdexercises the whole surface: schemas, sheets, active effects, initiative, automation, and a content pack.
#Next
Read The package kinds for how the three fit together, then pick a guide.
Was this page helpful?