Dice Rolls
The dice roll system adds D&D-style skill checks to items. When a player uses an item with a dice_roll, they must roll against a difficulty class (DC) with branching outcomes.
Schema
"dice_roll": { "dc": 12, "dice": "1d20", "attempt_message": "You carefully try to pick the lock...", "completed_message": "You've already picked this lock.", "consume_on": "failure", "on_success": { "message": "Click! The lock opens.", "sets_flag": "lock_picked", "unlocks_dialogue": { "topic": "secret_info" }, "unlocks_exit": { "direction": "east", "room": "current_room_id" } }, "on_failure": { "message": "The pick snaps! You'll need another.", "sets_flag": "failed_lockpick" } }
Fields
| Field | Type | Default | Description |
|---|---|---|---|
dc |
number | required | Difficulty class (1-20). The roll must meet or exceed this number to succeed. |
dice |
string | "1d20" |
Dice notation. Standard format: NdS (N dice with S sides). |
attempt_message |
string | — | Message shown when the roll is initiated, before the player types ROLL. |
completed_message |
string | — | Message shown if the player tries to use the item after a successful roll. |
consume_on |
string | — | When to consume the item. One of: "failure", "success", "any". |
on_success |
object | required | Outcome when the roll meets or exceeds the DC. |
on_failure |
object | required | Outcome when the roll is below the DC. |
Outcome Objects
Both on_success and on_failure support the same set of directives:
| Field | Type | Description |
|---|---|---|
message |
string | Text displayed to the player describing the outcome. |
sets_flag |
string | Global flag set to true. |
unlocks_dialogue |
object | Unlocks a dialogue topic. Contains topic (string). |
unlocks_exit |
object | Unlocks an exit. Contains direction (string) and optional room (string, defaults to current room). |
consume_on
Controls when the item is removed from inventory after the roll:
| Value | Behavior |
|---|---|
"failure" |
Item is consumed only on a failed roll. Lets the player retry on success. |
"success" |
Item is consumed only on a successful roll. |
"any" |
Item is always consumed regardless of outcome. |
| (omitted) | Item is never consumed by the roll. |
The engine validates dice_roll items at startup. Items with dice_roll must have both on_success and on_failure, and consume_on must be one of "failure", "success", or "any". Invalid values produce validation errors.
Roll Flow
1. Player types use lockpick
2. Engine shows the attempt_message and prompts: "Type ROLL to roll the dice."
3. A pending_roll is set on the player state, blocking all other commands
4. Player types roll
5. Engine rolls the dice (e.g., 1d20), compares to DC
6. Executes the appropriate outcome (on_success or on_failure)
7. Applies directives (sets_flag, unlocks_dialogue, unlocks_exit)
8. Consumes item if consume_on matches the outcome
9. Clears the pending_roll, resuming normal gameplay
Difficulty Class Guide
| DC | Difficulty | Success Rate (1d20) |
|---|---|---|
| 5 | Very Easy | 80% |
| 8 | Easy | 65% |
| 10 | Medium | 55% |
| 12 | Moderate | 45% |
| 15 | Hard | 30% |
| 18 | Very Hard | 15% |
| 20 | Nearly Impossible | 5% |
Full Example
"ancient_scroll": { "name": "Ancient Scroll", "description": "A fragile scroll covered in arcane runes.", "keywords": ["scroll", "runes"], "dice_roll": { "dc": 14, "dice": "1d20", "attempt_message": "You begin to decipher the ancient runes...", "completed_message": "You've already deciphered this scroll.", "consume_on": "any", "on_success": { "message": "The runes glow and you understand their meaning! A hidden path is revealed.", "sets_flag": "scroll_deciphered", "unlocks_exit": { "direction": "north" } }, "on_failure": { "message": "The scroll crumbles to dust before you can finish reading it.", "sets_flag": "scroll_destroyed" } } }