✨ Sparks
Sparks are dynamic values you inject into any piece config using {{path}} syntax. They make your bot respond to real Discord data instead of hardcoded strings.
⚙️How Sparks Work
Type a spark anywhere in a piece's config field. When the Engine runs the piece, it replaces the spark with the live value from the current context.
Here's a Reply piece using sparks to personalize its message:
base.replyIf a spark path doesn't exist in the current context (e.g. an optional option that wasn't provided), it resolves to an empty string — no error. Use base.coalesce to provide fallbacks.
// Sparks use {{path}} in config fields — paths match the Canvas autocomplete.
// Spells: {{input.user.id}}, {{input.user.name}}, {{input.options.target.id}}
// messageCreate: {{message.content}}, {{message.author.id}}
// After Save Spark: {{score}}
// After Read Vault (as: "result"): {{result}}, {{result.0.coins}}
// After Split Text (as: "parts"): {{parts}}, {{parts.0}}, {{parts.length}}
// Packs: {{lib.filter.profanity}}Utility pieces like Split Text save a list spark. Use the whole list in Loop or Join ({{parts}}), or pick one item with an index ({{parts.0}} is the first).
base.text.splitbase.text.join💫All Spark Categories
Context sparks (Spells)
Live data when a user runs a slash command.
| Path | Type | Description |
|---|---|---|
{{input.guild.id}} | string | Your Discord server's unique ID |
{{input.guild.name}} | string | Your server's name |
{{input.guild.memberCount}} | string | How many members are in the server |
{{input.user.id}} | string | Who ran the command — Discord ID |
{{input.user.name}} | string | Who ran the command — username |
{{input.user.displayName}} | string | Who ran the command — nickname in this server |
{{input.channel.id}} | string | The channel this command was used in |
{{input.channel.name}} | string | The channel's name |
Flow sparks
Named by upstream pieces — use the name you set in as / name fields.
| Path | Type | Description |
|---|---|---|
{{<name>}} | varies | Named spark you set — use {{score}}, not vars.score |
{{<as>}} | array | All matching rows — e.g. {{result}} |
{{<as>.length}} | number | Number of rows returned |
{{<as>.0.<column>}} | varies | First row column — e.g. {{result.0.coins}} |
{{<as>}} | varies | Current loop item — name from “Call each item” field |
{{<as>}} | string | number | Result spark named in the piece config |
Library sparks (Packs)
Pre-built values from Booster Packs.
| Path | Type | Description |
|---|---|---|
{{lib.filter.profanity}} | array | Array of common profanity and strong language |
{{lib.filter.slurs}} | array | Array of racial, ethnic, and identity-based slurs |
{{lib.filter.spam_phrases}} | array | Array of common spam and scam phrases |
{{lib.filter.discord_invite}} | string (regex) | Regex — detects Discord invite links (discord.gg/...) |
{{lib.filter.external_links}} | string (regex) | Regex — detects any http or https URL |
{{lib.filter.excessive_caps}} | string (regex) | Regex — detects 4+ consecutive uppercase characters (SHOUTING) |
{{lib.validate.email}} | string (regex) | Regex — validates email address format (user@domain.tld) |
{{lib.validate.url}} | string (regex) | Regex — validates http/https URLs |
{{lib.validate.phone}} | string (regex) | Regex — validates international phone numbers (E.164 style, optional +) |
{{lib.validate.discord_id}} | string (regex) | Regex — validates Discord snowflake IDs (17–20 digit numbers) |
{{lib.validate.discord_invite}} | string (regex) | Regex — validates a Discord invite link or code |
{{lib.validate.hex_color}} | string (regex) | Regex — validates hex color codes (#RGB or #RRGGBB) |
{{lib.validate.ip_address}} | string (regex) | Regex — validates IPv4 addresses (0.0.0.0 – 255.255.255.255) |
{{lib.validate.number_only}} | string (regex) | Regex — validates that a string contains only digits (0–9) |
🔀Using Sparks in Conditions
Condition pieces evaluate expressions — use sparks to compare live values.
base.conditionPick a rule in the Condition piece inspector — these are the operator ids the Engine understands:
isemptyisnotemptyistrueisfalseeqneqeqcicontainscontainscinotcontainsnotcontainscistartswithstartswithciendswithendswithcigtltgtelteinlistinlistcinotinlistcontainsanystartswithanyendswithanymatchesnotmatchesleft: {{score}}, operator: gte, right: 100number comparisonleft: {{input.user.id}}, operator: eq, right: {{targetId}}string equalityleft: {{message.content}}, operator: startswith, right: !prefix command checkleft: {{result}}, operator: isnotemptycheck if Read Vault found rows🎴Library Sparks from Packs
Booster Packs add pre-built values to your bot's spark library.
Once a pack is added to your bot, its sparks appear in the Canvas autocomplete under the Library category. Use them in any condition or config field.
base.condition