Skip to main content

Plans and Screen Settings

File: data/<namespace>/spb/plan/<path>.json. A Plan defines the complete starting flow; see the tutorial for a working minimal example. Plans have no schema-version field.

Plan fields​

FieldTypeRequiredDefaultPurpose
titleText componentnono headingScreen heading and narration title; no fallback to the mod name
descriptionText componentnoomittedPlan description; the current main screen does not render a top description
activationObjectnosee belowAutomatic activation and priority
inputsName → NumberProviderno{}External values captured at session creation
resourcesResourceBinding arrayyes—Bound Saturn resources
presetsPreset arrayno[]Left sidebar presets
groupsArray of IDs or #tagsyes—Ordered Group references
completion_rulesCompletion rule arrayno[]Conditions that must all pass for confirmation
outcomesOutcome arrayno[]Rewards derived from the final state
uiObjectnosee belowScreen dimensions and closing rules

Write text components explicitly as {"text":"Text"} or {"translate":"example.plan.title"}. Bare strings are translation keys. Put language files in a client resource pack, for example assets/example/lang/en_us.json.

Automatic activation​

activation fieldTypeRequiredDefaultPurpose
on_first_joinBooleannofalseOffer the plan at login to players who have not completed it
priorityIntegerno0Higher values win when multiple plans apply
conditionSaturn EntityConditionnoalways trueAutomatic entry condition evaluated against real player state

Equal priorities are resolved by ascending plan ID. Only one plan is edited at a time; after completing an automatic plan, the next eligible plan is offered on a later login. Explicit commands or actions can specify a nonautomatic plan; activation.condition filters the automatic entry point.

Resource bindings​

ResourceBinding fieldTypeRequiredDefaultPurpose
resourceSaturn resource IDyes—An existing resource, bound only once per plan
initialNumberProvidernocurrent real valueEvaluated only when creating a new session
quantumFinite positive numberno1Smallest unit, such as 0.25, for precision checks
commitreplace / discardnoreplaceWrite the final value on confirmation, or use it only in the draft
displayBooleannotrueShow the resource in the bottom bar
nameText componentnogenerated translation keyDisplay name; defaults to spb.resource.<namespace>.<path>
{
"resources": [
{"resource": "example:points", "initial": 8, "name": {"text": "Points"}},
{"resource": "example:strength", "name": {"text": "Strength"}},
{"resource": "example:preview", "commit": "discard", "display": false}
]
}

This is a Plan fragment; define the three referenced resources separately. Formulas use names generated from IDs, such as base_example_points and resource_example_points. Resources have no configurable key.

Every edit recalculates from the frozen baseline and complete selection. The draft does not change real player resources; successful confirmation writes replace resources. discard resources still take part in contributions, bounds and precision checks, but are not written back.

Physical bounds come from the Saturn resource definition. Overspending, bound violations and values misaligned with quantum block submission; balances are not clamped into validity. For fractional units, check resource defaults, contributions and final values. The first bound resource is the primary currency in price lines; other reduced resources retain their negative sign.

Reset keeps the baseline; reopening keeps the saved draft; refreshing reads current real resources without evaluating initial again. Prefer dedicated starting resources so other gameplay does not change the same balance during editing.

Captured inputs​

{
"inputs": {
"bonus": 2,
"roll": {"type": "saturn:uniform", "min": 1, "max": 4}
}
}

Input map names remain configurable: formulas read input_bonus and input_roll. Names must be nonempty and use only letters, digits and underscores accepted by Saturn variable names. Values are evaluated and saved at new-session creation. Clicks, Reset and reconnecting do not reroll them; an explicit refresh captures them again.

Inputs and initial are evaluated before selection editing and should not depend on final draft variables. Other NumberProviders can read real player state.

Presets​

Preset fieldTypeRequiredDefaultPurpose
nameText componentyes—Sidebar label
descriptionText componentnoomittedDescription
iconSaturn IconReferencenoomittedIcon, such as {"id":"minecraft:iron_sword"}
selectionsFull Option ID → non-negative integerno{}Complete selection; omitted options have quantity 0

Presets have no key field. Their one-based list positions produce preset_1, preset_2, etc. Reordering changes these identities, and duplicate preset contents are allowed.

Applying a preset replaces the complete draft without changing the baseline. Invalid references, hard limits, single-choice structure or candidate availability leave the original draft intact. A preset that violates point or dynamic completion limits can remain as a draft to repair.

Completion rules​

Rule fieldTypeRequiredDefaultPurpose
keyNonblank stringyes—Diagnostic identifier
conditionSaturn EntityConditionyes—Condition that must pass
messageText componentnofailure message containing the keyShown when the rule fails

All rules must pass, together with resource bounds, group and option limits. See formulas and comparisons for exact-zero, non-negative and range conditions.

Screen settings​

ui fieldTypeRequiredDefaultPurpose
preset_sidebar_widthInteger, GUI logical pixelsno100Desired preset sidebar width, constrained by the layout
max_widthInteger, GUI logical pixelsno0A positive maximum window width; 0 uses the current logical screen
max_heightInteger, GUI logical pixelsno0A positive maximum window height; 0 uses the current logical screen
allow_close_before_completeBooleannofalseAllow saving and closing before confirmation

These dimensions already account for Minecraft GUI scale; they are not physical pixels. Closing is locked by default, even when point rules pass. With early closing enabled, dismissal still waits for a server acknowledgement. Damage protection while open is always handled by the server and has no separate setting. Plans without presets hide the sidebar.