Skip to content

Required

Syntax: config <ID> { <CHILDREN> }

Defines basic required info about the System to properly generate.

Children ​

Id ​

id = "<STRING>": A machine-friendly id such as "my-system"

Label ​

label = "<STRING>": A human-friendly id such as "My System"

Description ​

description = "<STRING>": A human-friendly description of the system

Author ​

author = "<STRING>": A human-friendly string of who wrote the system FSDL

Theme ​

theme { <TOKEN>* }: Declarative style tokens (colors, fonts, borders, sizing) that control the system's look from source. Compiles to CSS custom properties applied across every sheet. See Theming & Styles for the full vocabulary.

kotlin
theme {
    primary: #c9a227,
    background: #16130f,
    text: #d6cfbf,
    border  { color: #3a3128, radius: 0 },
    heading { color: #c9a227, transform: "uppercase" }
}

Sidecar Stylesheets ​

Two optional .scss files (paths relative to the .isdl) for bespoke styling a theme token can't express — web fonts, grain, shadows, chat-card tweaks. Both are compiled and auto-scoped to your system. See Theming & Styles.

  • sheetStyles = "<STRING>": scoped to the generated character sheets only.
  • globalStyles = "<STRING>": scoped to the whole system (sheets and chat cards, dialogs, and other surfaces).

User Colors ​

userColors = <BOOLEAN>: Whether each sheet shows a Setup Colors picker letting players choose their own primary/secondary/tertiary colors (default true). Set false for an art-directed system whose look should stay fixed. See Theming & Styles.

Settings ​

settings { <SCOPE> { <SETTING>* }* }: Declares configurable Foundry game settings (game.settings.register) that appear in the system's settings menu and can be read and written from logic.

Settings are grouped by scope:

  • world { ... } — one shared value for the whole world. Only a GM can change it.
  • client { ... } — a per-user value, stored on each client.

Inside a scope, declare settings with the field type keywords. Supported types are boolean, number, string, and choice<string>.

kotlin
settings {
    client {
        boolean ShowToHit(initial: true, hint: "Show the to-hit number on character sheets")
    }
    world {
        number StartingKarma(initial: 3)
        choice<string> KarmaInChat(choices: ["Never", "GM Only", "Everyone"], initial: "GM Only")
    }
}

Setting parameters:

  • initial: — the default value. Must be a static literal matching the type (true/false, a number, or a string).
  • choices: — for choice<string>, the list of allowed string values.
  • label: — the display name shown in the settings menu (defaults to a humanized version of the name).
  • hint: — optional descriptive text shown under the name.

Reading and writing settings in logic ​

Reference a setting from logic with System.<Name>. A read can be used in any expression position — if conditions, comparisons, return values, calculated value: fields, and chat cards.

kotlin
// read in an if condition
if (System.ShowToHit) {
    log("To-hit is visible")
}

// read in a calculated value
number EffectiveKarma(value: { return System.StartingKarma + 1 })

To gate a field on a setting with visibility:, use a method block that returns a Visibility value (visibility: expects a Visibility.X, not a raw boolean):

kotlin
string ToHit(visibility: {
    if (System.ShowToHit) { return Visibility.default }
    return Visibility.hidden
})

You can also assign to a setting to change it. Because a world-scoped setting can only be changed by a GM, a write to one must be wrapped in an if (User.isGM) check (the generator enforces this). Client-scoped writes have no such restriction.

kotlin
// world setting: must be GM-gated
if (User.isGM) {
    System.StartingKarma = System.StartingKarma + 1
}

// client setting: no restriction
System.ShowToHit = false

Example ​

kotlin
config FabulaUltima {
    label = "Fabula Ultima"
    id = "fabula-ultima"
    description = "Test generation of Fabula Ultima"
    author = "Cody Swendrowski"

    settings {
        world {
            choice<string> KarmaInChat(choices: ["Never", "GM Only", "Everyone"], initial: "GM Only")
        }
    }
}