Rolls and expressions
Use safe display expressions and server-authoritative dice without mixing their roles.
Aether has two small languages with different authority.
#Expressions derive display values
The expression evaluator reads plain data and supports arithmetic, comparison, boolean logic,
ternaries, dotted paths, and the whitelisted functions floor, ceil, round, abs, min, and
max. It has no eval, globals, prototype access, or mutation.
Native view builders produce expression artifacts without writing source strings:
const current = document();
const modifier = expr.floor(
expr.divide(expr.subtract(current.number("system.strength"), 10), 2),
);Expressions are suitable for a sheet label or formula interpolation. They are not an authority boundary and do not apply damage.
#Dice produce explicit results
The core roller accepts arithmetic, parentheses, percentile dice, keep and drop modifiers,
exploding dice, and rerolls. Examples include 1d20+5, 2d20kh1, 4d6dl1, 1d6!, and 1d20r1.
The result records each die, dropped dice, grouped terms, the flat modifier, and total.
In Aether, the server creates and routes the roll entry. A hidden roll is controlled by the entry's
audience, not by a magic prefix in the formula. The obsolete gm prefix is rejected.
#Automation joins the two safely
A system can declare an initiative formula and named automation scripts. Scripts execute in the QuickJS automation sandbox. They can roll, read projected documents, keep namespaced state, and emit mutations. The authoritative server revalidates each emitted patch and its permission.
return {
documents: [character],
initiative: "1d20 + ${floor((strength - 10) / 2)}",
automation: {
scripts: [{ id: "roll-damage", name: "Roll damage", source: scriptSource }],
},
};The string inside ${...} reads the combatant's system data. The surrounding dice formula is then
rolled for the authoritative initiative value.
Use the dice preview on interactive previews for parser
feedback. Use systems/demo-system/src/index.ts and packages/automation/test/sandbox.test.ts for
maintained automation examples.