Update readme with schemas

This commit is contained in:
Endeavorance 2025-03-20 14:24:56 -04:00
parent d1b632e83c
commit 655a105924
2 changed files with 136 additions and 23 deletions

135
README.md
View file

@ -1,6 +1,6 @@
# Playbill Builder CLI
This is a CLI tool for compiling YAML files into a validated Playbill for [Proscenium](https://proscenium.game)
This is a CLI tool for compiling Markdown and YAML files into a validated Playbill for [Proscenium](https://proscenium.game)
## Usage
@ -9,22 +9,139 @@ Usage:
muse [/path/to/binding.yaml] <options>
Options:
--check Only load and check the current binding and resources,
but do not compile
--write Write the output to a file. If not specified, outputs to stdout
--outfile Specify the output file path [default: playbill.json]
--verbose, -v Verbose output
--help, -h Show this help message
--check Only load and check the current binding and resources, but do not compile
--outfile, -o Specify the output file path. If not specified, output to stdout
--watch, -w Watch the directory for changes and recompile
--renderer, -r Specify the output renderer. Options: json, html
--help, -h Show this help message
```
## Binding File
```yaml
$binding: playbill # Required
id: the-playbill-id # Required
name: My Playbill # Required
author: My Name # Required
version: 0.0.1 # Required
files: # Optional
- "**/*.yaml"
styles: # Optional
- stylesheet.css
terms: # Optional
Some Term: Some Definition
Another Term: Another Definition
```
## Definition Shapes
These YAML representations of definitions show the properties available for each Playbill component.
Note that every Playbill component definition can define the following properties:
```yaml
id: some-hypenated-id # default: slug-ified file name
name: The Name of the Component # default: Name of the containing file
description: A markdown-enabled description # default: Placeholder / empty
categories: # default: No categories
- list
- of
- categories
```
### Ability Definition
```yaml
$define: ability
type: action | cue | trait
ap: 0
hp: 0
ep: 0
xp: 0
damage: 0
damageType: phy | arc
roll: none | attack | fate | <any talent>
```
### Blueprint Definition
```yaml
$define: blueprint
species: some-hypenated-id
items:
- item-id
- item-id-two
- item-id-three
abilities:
- ability-id
- ability-id-two
- ability-id-three
ap: 0
hp: 0
ep: 0
xp: 0
muscle: novice | adept | master
focus: novice | adept | master
knowledge: novice | adept | master
charm: novice | adept | master
cunning: novice | adept | master
spark: novice | adept | master
```
### Item Definition
```yaml
$define: item
type: wielded | worn | trinket
rarity: common | uncommon | rare | legendary
affinity: none | attack | fate | <any talent>
damage: 0
damageType: phy | arc
hands: 1 | 2 # Only for wielded items
slot: headgear | outfit | gloves | boots | adornment | unique # Only for worn items
```
### Method Definition
```yaml
$define: method
curator: Someone
abilities:
- [rank-1-ability-id-one, rank-1-ability-id-two]
- [rank-2-ability-id-one]
```
### Resource Definition
```yaml
$define: resource
type: text | image | table
url: https://example.com/image.jpeg # Only for image resources
data: <a 2-d array of strings> # Only for table resources
```
### Rule Definition
```yaml
$define: rule
overrule: another-rule-id # Optional
order: 0 # Optional
```
### Species Definition
```yaml
$define: species
hands: 2
abilities:
- some-ability-id
- another-ability-id
ap: 0
hp: 0
ep: 0
xp: 0
muscle: novice | adept | master
focus: novice | adept | master
knowledge: novice | adept | master
charm: novice | adept | master
cunning: novice | adept | master
spark: novice | adept | master
```

View file

@ -17,18 +17,14 @@ import {
import { z } from "zod";
const Base = z.object({
// Required -- defines the type of component
$define: z.string(),
});
const Info = Base.extend({
id: z.string(), // TODO: Validate ID shapes
name: z.string().default("Unnamed Component"),
description: z.string().default("No description provided"),
categories: z.array(z.string()).default([]),
});
const AbilitySchema = Info.extend({
const AbilitySchema = Base.extend({
$define: z.literal("ability"),
type: z.string().default("action"),
ap: z.number().int().default(0),
@ -40,7 +36,7 @@ const AbilitySchema = Info.extend({
roll: z.string().default("none"),
});
const BlueprintSchema = Info.extend({
const BlueprintSchema = Base.extend({
$define: z.literal("blueprint"),
species: z.string(),
items: z.array(z.string()).default([]),
@ -62,7 +58,7 @@ const GlossarySchema = Base.extend({
terms: z.record(z.string(), z.string()),
});
const BaseItem = Info.extend({
const BaseItem = Base.extend({
$define: z.literal("item"),
rarity: z.string().default("common"),
affinity: z.string().default("none"),
@ -78,43 +74,43 @@ const ItemSchema = z.discriminatedUnion("type", [
}),
BaseItem.extend({
type: z.literal("worn"),
hands: z.number().int().default(1),
slot: z.string().default("unique"),
}),
BaseItem.extend({
type: z.literal("trinket"),
}),
]);
const MethodSchema = Info.extend({
const MethodSchema = Base.extend({
$define: z.literal("method"),
curator: z.string().default("Someone"),
abilities: z.array(z.array(z.string())).default([]),
});
const ResourceSchema = z.discriminatedUnion("type", [
Info.extend({
Base.extend({
$define: z.literal("resource"),
type: z.literal("text"),
}),
Info.extend({
Base.extend({
$define: z.literal("resource"),
type: z.literal("image"),
url: z.string(),
}),
Info.extend({
Base.extend({
$define: z.literal("resource"),
type: z.literal("table"),
data: z.array(z.array(z.string())),
}),
]);
const RuleSchema = Info.extend({
const RuleSchema = Base.extend({
$define: z.literal("rule"),
overrule: z.nullable(z.string()).default(null),
order: z.number().int().default(Number.POSITIVE_INFINITY),
});
const SpeciesSchema = Info.extend({
const SpeciesSchema = Base.extend({
$define: z.literal("species"),
hands: z.number().int().default(2),
abilities: z.array(z.string()).default([]),