Macros Guide
Start your journey on the stage
Macros
Macros are little placeholders you drop into your prompts, character cards, and lorebooks that get replaced with real values before the AI sees them. Instead of hardcoding a character's name or the time of day, you write {{char}} or {{time}} and RoleCall fills in the blanks.
They look like this: {{macro_name}}. Some accept arguments separated by ::, like {{random::1::100}}.
This guide walks you through macros from the basics to advanced patterns. By the end, you'll be writing dynamic prompts that track state, branch on conditions, and inject game mechanics — all without touching code.
Your First Macros
The simplest macros just drop in a name or value. Try putting these in a system prompt or character description:
{{char}} turns to {{user}} and smiles.
If the character is "Elara" and you're "Marcus", the AI sees:
Elara turns to Marcus and smiles.
That's it. No setup, no configuration. Here are the identity macros you'll use constantly:
| Macro | What It Becomes |
|---|---|
{{char}} | The character's name |
{{user}} | Your display name |
{{persona}} | Your persona description text |
{{model}} | The AI model being used |
Why this matters: When you fork someone else's character or share a preset, macros mean the text adapts automatically. No find-and-replace needed.
Pulling From Character Cards
You can reference any field from the current character card. This is especially useful in presets, where you don't know which character will be used:
Here is the character you will be playing:
Name: {{char}}
Description: {{description}}
Personality: {{personality}}
Scenario: {{scenario}}
| Macro | Field |
|---|---|
{{description}} | Character description |
{{personality}} | Personality field |
{{scenario}} | Current scenario |
{{firstMessage}} | The greeting / first message |
{{mesExamples}} | Example dialogues (formatted) |
{{charTags}} | Tags as comma list |
{{charCreator}} | Creator's username |
There are also pronoun macros that resolve based on the character's gender setting:
{{char}} drew {{their}} sword and steadied {{themself}}.
Becomes "Elara drew her sword and steadied herself" or "Kael drew his sword and steadied himself" — automatically.
Available forms: {{they}}, {{them}}, {{their}}, {{theirs}}, {{themself}} (and capitalized versions like {{They}}). For user pronouns, prefix with u: {{uthey}}, {{uthem}}, etc.
Adding Randomness
Want the AI to encounter unpredictable situations? Random macros inject variety into every generation:
The weather today is {{random::sunny::overcast::rainy::stormy}}.
A mysterious stranger approaches. They seem {{random::friendly::suspicious::nervous::hostile}}.
Each time this prompt is processed, the AI gets a different weather and stranger disposition.
Dice Rolls
For tabletop-style mechanics, use standard dice notation:
You attempt to pick the lock. [Roll: {{roll::1d20}}]
The dragon's breath deals {{roll::3d6+5}} fire damage.
The Full Randomness Toolkit
| Macro | What It Does | Example |
|---|---|---|
{{random}} | Number 0–100 | 73 |
{{random::1::10}} | Number in range | 7 |
{{random::a::b::c}} | Pick from options | b |
{{pick::a::b::c}} | Same as above | c |
{{roll::2d6}} | Standard dice | 8 |
{{roll::1d20+5}} | Dice with modifier | 17 |
{{coinflip}} | Heads or Tails | Heads |
{{coinflip::win::lose}} | Custom sides | win |
{{percent}} | Percentage 0–100 | 42 |
{{shuffle::a::b::c}} | All items, shuffled | c, a, b |
{{weighted::dragon::10::goblin::90}} | Weighted pick | goblin (90%) |
Time and Date
Inject real-world time into your prompts. Useful for atmospheric flavor or time-aware scenarios:
It is currently {{time}} on {{weekday}}, {{date::long}}.
The season is {{season}} and the moon is {{moonPhase}}.
It is currently 3:42 PM on Tuesday, March 10, 2026. The season is spring and the moon is Waxing Crescent.
| Macro | Output |
|---|---|
{{time}} | 3:42 PM (use {{time::24}} for 24h) |
{{date}} | 3/10/2026 (try {{date::long}} for "March 10, 2026") |
{{weekday}} | Tuesday |
{{month}} | March |
{{year}} | 2026 |
{{isodate}} | 2026-03-10 |
{{season}} | spring (use {{season::south}} for southern hemisphere) |
{{moonPhase}} | Waxing Crescent |
{{idle_duration}} | Time since last message ("5 minutes", "2 hours") |
{{datetimeformat::HH:mm, ddd MMM DD}} | Custom format: "15:42, Tue Mar 10" |
Variables — Tracking State
This is where macros get powerful. Variables let you store values that persist throughout a conversation. Think of them as the AI's "memory" for game state, mood, relationships, and more.
Setting and Getting
{{setvar::mood::calm}}
{{setvar::location::tavern}}
These return nothing visible (they just store the value). To read them back:
{{char}} is currently feeling {{getvar::mood}} at the {{getvar::location}}.
Elara is currently feeling calm at the tavern.
Dot Notation — The Easy Way
Writing {{getvar::mood}} everywhere gets verbose fast. Dot notation is the shorthand:
| Shorthand | Same As |
|---|---|
{{.mood}} | {{getvar::mood}} |
{{.mood = calm}} | {{setvar::mood::calm}} |
{{.hp += 10}} | {{addvar::hp::10}} |
{{.hp -= 5}} | {{addvar::hp::-5}} |
{{.counter++}} | {{incvar::counter}} |
{{.counter--}} | {{decvar::counter}} |
You can also nest into objects: {{.stats.strength}}, {{.inventory.0}}.
Numeric Variables
Variables can hold numbers and you can do math on them:
{{.hp = 100}}
{{.gold = 50}}
{{// Later, after a fight:}}
{{.hp -= 25}}
{{.gold += 100}}
HP: {{.hp}}/100 | Gold: {{.gold}}
HP: 75/100 | Gold: 150
Global Variables
Normal variables are per-chat — they reset when you start a new conversation. Global variables persist across all chats:
{{setglobalvar::totalDeaths::0}}
{{addglobalvar::totalDeaths::1}}
You have died {{getglobalvar::totalDeaths}} times across all adventures.
Shorthand: {{$totalDeaths}} reads a global variable.
Arrays
Variables can also hold lists:
{{pushvar::inventory::Iron Sword}}
{{pushvar::inventory::Health Potion}}
{{pushvar::inventory::Torch}}
You are carrying: {{listvar::inventory}}
Items: {{countvar::inventory}}
You are carrying: Iron Sword, Health Potion, Torch Items: 3
Use {{popvar::inventory}} to remove and return the last item.
Block Variables
Need to store multi-line content? Use block syntax:
{{setvar::backstory}}
{{char}} grew up in a small fishing village on the northern coast.
At sixteen, {{they}} left home to study at the Academy of Arcane Arts.
{{they}} never returned.
{{/setvar}}
Everything between {{setvar::backstory}} and {{/setvar}} becomes the value.
Conditionals — Branching Logic
Now things get interesting. Conditionals let different text appear based on the current state.
Inline If
The simplest form fits on one line:
{{if::{{.mood}}::{{char}} is in a {{.mood}} mood today.}}
This only shows the text if the mood variable is set (truthy). You can add an else:
{{if::{{.isNight}}::The stars are out.::The sun is shining.}}
Block If — For Longer Sections
When you need more than a one-liner:
{{if {{compare::{{.relationship}}::>=::80}}}}
{{char}} greets {{user}} with a warm hug.
"I'm so glad you're here!"
{{else}}
{{char}} nods politely at {{user}}.
"Can I help you with something?"
{{/if}}
The {{compare}} macro returns true or false based on the operator. Here it checks if the relationship score is 80 or higher.
SillyTavern compatibility: {{#if}} works as an alias for {{if}} in block conditionals.
Comparison Operators
Use with {{compare::value1::operator::value2}}:
| Operator | Meaning |
|---|---|
== | Equal (case-insensitive) |
!= | Not equal |
=== | Exact match (case-sensitive) |
>, <, >=, <= | Numeric comparison |
contains | Is substring present? |
startswith | Starts with? |
endswith | Ends with? |
matches | Regex test |
Logical Operators
Combine conditions:
{{if {{and::{{compare::{{.hp}}::>::0}}::{{compare::{{.mood}}::!=::unconscious}}}}}}
{{char}} is still standing.
{{/if}}
{{and::a::b::c}}— all must be truthy{{or::a::b::c}}— any must be truthy{{not::value}}— flips true/false
Truthiness
What counts as "false"? These values: empty string, "false", "0", "null", "undefined". Everything else is considered true.
Switch — Multiple Branches
When you have many possible values, switch is cleaner than nested ifs:
{{switch::{{.weather}}::
rain:You hear raindrops on the roof.::
snow:Frost covers the windows.::
storm:Thunder rattles the shutters.::
Clear skies stretch overhead.}}
The last entry without a colon is the default. Each case is value:result, separated by ::.
Nesting Macros
Macros can go inside other macros. The inner ones resolve first:
{{getvar::{{char}}_mood}}
This first resolves {{char}} to "Elara", then gets the variable Elara_mood. Useful for per-character state in group chats.
Another common pattern — dynamic variable names:
{{setvar::{{char}}_trust::50}}
{{setvar::{{char}}_met::true}}
{{if::{{getvar::{{char}}_met}}::You've met {{char}} before.::This is your first encounter.}}
Maximum nesting depth is 100 levels, which is far more than you'll ever need.
Practical Example: A Dynamic System Prompt
Let's combine everything into a real system prompt:
{{// Set initial state if not already set}}
{{if::{{not::{{hasvar::initialized}}}}::{{setvar::initialized::true}}{{setvar::mood::neutral}}{{setvar::trust::30}}{{setvar::location::village square}}}}
{{// Atmosphere based on time}}
The current time is {{time}} on {{weekday}}.
{{switch::{{season}}::
spring:Flowers bloom along the cobblestone paths.::
summer:The air shimmers with heat.::
autumn:Fallen leaves crunch underfoot.::
winter:A thin layer of frost covers everything.}}
{{// Relationship context}}
{{if {{compare::{{.trust}}::>=::70}}}}
{{char}} considers {{user}} a trusted friend and speaks openly.
{{else}}{{if {{compare::{{.trust}}::>=::40}}}}
{{char}} is warming up to {{user}} but remains somewhat guarded.
{{else}}
{{char}} is wary of {{user}} and watches them carefully.
{{/if}}{{/if}}
{{// Random event (10% chance)}}
{{if {{compare::{{random::1::10}}::==::1}}}}
[A surprising event occurs: {{random::a traveling merchant arrives::a distant bell tolls::a cat crosses your path::storm clouds gather}}]
{{/if}}
Current scene: {{.location}}
{{char}}'s mood: {{.mood}}
This prompt adapts to the season, tracks trust, occasionally throws in random events, and maintains state across the conversation — all with macros.
Text Processing
Transform text on the fly:
| Macro | Input → Output |
|---|---|
{{upper::hello}} | HELLO |
{{lower::HELLO}} | hello |
{{title::hello world}} | Hello World |
{{trim:: hello }} | hello |
{{length::hello}} | 5 |
{{replace::hello::l::r}} | herro |
{{split::a,b,c::,::1}} | b (index 1) |
{{join:: and ::a::b::c}} | a and b and c |
{{repeat::ha::3}} | hahaha |
{{truncate::long text here::8}} | long tex... |
{{reverse::hello}} | olleh |
Comments
Leave notes in your prompts that are invisible to the AI:
{{// This section handles trust mechanics}}
{{// TODO: add loyalty system later}}
Comments are stripped from the output entirely.
RPG & Game Mechanics
RoleCall includes built-in helpers for tabletop-style gameplay. These read from a stats variable object.
Setting Up Stats
{{setvar::stats::{"strength":14,"dexterity":12,"wisdom":10,"charisma":16}}}
{{setvar::hp::100}}
{{setvar::maxhp::100}}
{{setvar::gold::50}}
{{setvar::level::1}}
{{setvar::xp::0}}
Using Stat Checks
{{char}} attempts to force the door open.
Result: {{check::strength::15::verbose}}
Result: Success (rolled 12 + 14 = 26 vs DC 15)
The check macro rolls a d20, adds the stat value, and compares against the DC (difficulty class).
Display Helpers
HP: {{hp}} | Level: {{level}} | XP: {{xp}} | Gold: {{gold}}
{{progress::{{.hp}}::{{.maxhp}}}}
Inventory: {{inventory}}
HP: 75/100 | Level: 1 | XP: 0 | Gold: 50 [######----] 75% Inventory: Iron Sword, Health Potion
Convenience Aliases
These shorthand macros read from common variable names — you don't need {{getvar}}:
| Macro | Reads Variable |
|---|---|
{{mood}} | mood |
{{location}} | location |
{{relationship}} | relationship |
{{timeofday}} | timeOfDay |
{{trust}} | trust |
{{affection}} | affection |
{{tension}} | tension |
{{weather}} | weather |
Set them with dot notation: {{.mood = happy}}, {{.location = dark forest}}.
User-Defined Macros
Create reusable templates with parameters:
Define
{{macro::describe::{{$1}} looks {{$2}} today, wearing {{$3}}.}}
Call
{{macro::describe::{{char}}::tired::a tattered cloak}}
Elara looks tired today, wearing a tattered cloak.
Placeholders {{$1}}, {{$2}}, etc. get replaced with the arguments you pass. Useful for repeated patterns across a complex prompt.
Note: User-defined macros are ephemeral — they only exist during the current prompt processing. Define them at the top of the prompt where you'll use them.
Chat Context Macros
Access information about the current conversation:
| Macro | What It Returns |
|---|---|
{{lastMessage}} | Most recent message (any role) |
{{lastUserMessage}} | Most recent user message |
{{lastCharMessage}} | Most recent character message |
{{message::-1}} | Message at index (negative = from end) |
{{recentMessages::5}} | Last 5 messages, formatted |
{{messageCount}} | Total messages in the chat |
{{memories}} | Chat memory summaries |
{{summary}} | Latest auto-generated summary |
Token-Aware Macros
Some macros are context-window-aware and accept token limits:
{{message history::2000::20}}
This includes up to 2000 tokens of history, capped at 20 messages. Useful in lorebook entries or depth prompts where you want a summary without blowing the budget.
Stats & Tokens
Monitor your context budget from within prompts:
| Macro | What It Returns |
|---|---|
{{tokencount}} | Current prompt token count |
{{tokenbudget}} | Maximum context window size |
{{tokenremaining}} | How many tokens are left |
{{responsetokens}} | Max response token setting |
{{contextusage}} | Usage as a percentage |
Lorebook Macros
Access lorebook data from your prompts:
Triggered lore entries: {{triggeredentries}}
Active lorebooks: {{lorebooklist}}
Lore tokens used: {{lorebooktokens}}
Pull a specific entry's content: {{lorebook::Dragon Lore}}.
Pick a random entry from an inclusion group: {{lorebookrandom::Rumors}}.
Use {{outlet::name}} to create named injection points that lorebook entries can target.
Where Can I Use Macros?
Macros work everywhere in the prompt pipeline:
- Presets — System prompts, prompt stack entries, all injection positions
- Character Cards — Description, personality, scenario, first message, example dialogues
- Lorebooks — Entry content and trigger keywords
- Personas — User persona descriptions
- Author Notes — Depth notes and creator notes
Tips & Patterns
Start simple. Use {{char}} and {{user}} in your first prompt. Add variables later when you want state.
Use comments for organization. {{// TRUST SYSTEM}} helps you find things in complex prompts.
Debug with {{allvars}}. Temporarily add this macro to dump all current variables as JSON — great for seeing what state the AI is working with.
Set defaults early. Put your {{setvar}} calls at the top of your system prompt, inside a guard:
{{if::{{not::{{hasvar::initialized}}}}::{{setvar::initialized::true}}{{setvar::hp::100}}{{setvar::mood::neutral}}}}
This ensures variables are only set once, not reset every turn.
Combine randomness with conditions. A random encounter that only fires when tension is high:
{{if {{compare::{{.tension}}::>=::8}}}}
{{if {{compare::{{random::1::4}}::==::1}}}}
A shadowy figure emerges from the alley ahead.
{{.tension -= 3}}
{{/if}}
{{/if}}
Use block setvar for long text. Don't try to cram a paragraph into {{setvar::lore::very long text here...}}. Use block syntax instead for anything multi-line.
Use {{noop}} to eat unwanted whitespace. Block macros like {{if}}...{{/if}} can leave blank lines. Place {{noop}} on the same line as the closing tag to suppress them.