-
Notifications
You must be signed in to change notification settings - Fork 191
Documentation for stack scrolls.lic
stack-scrolls is a dr-scripts management suite for spell scroll stackers (folios, tomes, codices, booklets) in DragonRealms. It reads the contents of one or more stackers into a cached map, files loose scrolls into the correct sections, retrieves single copies on demand, reports your inventory in several views, and runs simulate-then-confirm maintenance plans (prune, consolidate, clean).
Every operation that removes or moves scrolls previews a plan first and only acts when you add confirm. By default nothing is ever trashed: scrolls that do not fit are stowed safely.
- Requirements
- Quick Start
- YAML Configuration
- Commands
- Keep and Discard Filtering
- Copy Limits
- Excess Scrolls: Stow or Trash
- How Stacking Works
- Understanding consolidate
- Settings Reference
- Migrating from the Legacy Format
- Command Quick Reference
- Troubleshooting
- Lich5 with the dr-scripts dependency installed and up to date.
- The bundled
spellsdata (ships with dr-scripts). It supplies spell abbreviations and mana types, used byget, themanafilter, and the abbreviations shown in listings. The script still runs without it; those features degrade gracefully.
- One or more scroll stackers (a scroll folio, tome, codex, booklet, or similar). Each stacker holds a fixed number of slots (sections), and each section holds copies of a single spell (the game caps a section at 125 copies).
- The stackers reachable via
get my <stacker>, either loose in a worn container or inside a single holding container (seestacker_container).
At minimum you must define your stackers under a stack_scrolls: block. See YAML Configuration.
-
Add a
stack_scrolls:block to your character YAML listing your stackers:stack_scrolls: stackers: - scroll folio - blue tome stacker_container: haversack
-
Drop the loose scrolls you want to file into a container (for example your haversack).
-
Run the stacker over that container:
;stack-scrolls haversack -
Check what you have:
;stack-scrolls
That is the whole loop. The maintenance commands below (prune, consolidate, clean) are optional housekeeping you run occasionally.
Settings live under a nested stack_scrolls: block. A full example:
stack_scrolls:
# Required: the stacker items, in the order you want them filled.
stackers:
- scroll folio
- blue tome
- carmine codex
# Optional: the single container your stackers are stored in. If omitted,
# the script uses your default stow location for scrolls it sets aside.
stacker_container: haversack
# Optional whitelist. Empty (or absent) means keep every spell.
# Matches a spell's full NAME or ABBREVIATION, exactly (case-insensitive).
keep_scrolls: []
# Optional blacklist. Takes priority over keep_scrolls.
discard_scrolls:
- Frostbite
- Fire Ball
# When the stackers are full, should unstackable scrolls be trashed?
# false (default) = stow them safely; true = trash them.
trash_excess_scrolls: false
# Optional caps (both disabled if omitted).
max_scrolls_per_spell: 100 # global cap on total copies of any one spell
max_scrolls_per_slot: 125 # cap on copies in a single section (game max 125)
# Optional: write a timestamped per-run stats log. Default false.
log_statistics: false
# NOTE: worn_trashcan / worn_trashcan_verb are SHARED settings read from the
# TOP LEVEL of your profile (many scripts use one trash receptacle). Leave them
# where your other scripts already read them; do NOT move them under
# stack_scrolls.
worn_trashcan: bin
worn_trashcan_verb: dumpNotes:
-
stackersvalues are whatever you would type afterget my .... If a plain noun is ambiguous, use Lich dot notation to disambiguate, for examplescroll.folioorabyssal-black.codex. - The order of
stackersmatters for consolidate: it fills the first stacker, then the second, and so on, so the later ones can be emptied and removed. -
worn_trashcanandworn_trashcan_verbcontrol periodic emptying of a worn trash bin while trashing. They are optional and shared with other scripts.
All commands are prefixed with ;stack-scrolls. Commands that change anything (prune, consolidate, clean) only simulate until you add confirm.
Collect every scroll from a container and file each one into the correct stacker section.
;stack-scrolls <container>
Example:
;stack-scrolls haversack
For each scroll the script identifies the spell (by looking at it, or reading glyph scrolls), applies your keep and discard rules and limits, and pushes it into a matching section (creating the section if needed). Scrolls filtered out are trashed; scrolls that pass filters but do not fit are handled per Excess Scrolls. A summary prints at the end:
============================================================
SCROLL STACKING SUMMARY
============================================================
Total Processed: 24
Kept (Stacked): 21
Trashed: 2
Stowed (Excess): 1
Rejected by Limits: 0
------------------------------------------------------------
Per-Spell Breakdown:
Acid Splash P:3 K:3 T:0 S:0 R:0
Frostbite P:2 K:0 T:2 S:0 R:0
------------------------------------------------------------
============================================================
Show a flat, alphabetized list of every spell you have stacked, with counts, location, and page (slot) number.
;stack-scrolls
Example output:
================================================================================
SCROLLS
================================================================================
Spell Name Count Stacker Page
--------------------------------------------------------------------------------
Acid Splash (acidsplash) 5 blue tome 2
Heal (heal) 3 scroll folio 1
--------------------------------------------------------------------------------
Total: 2 scroll type(s)
================================================================================
Free Slots Remaining: 73
The first run reads your stackers into a cache; later commands reuse it until you reset (or run a maintenance command, which refreshes automatically).
A verbose overview: per-stacker usage, per-stacker contents, and a spell statistics table with mana types.
;stack-scrolls summary
Example (abbreviated):
================================================================================
STACKER OVERVIEW
================================================================================
Stacker Total Used Empty Spells Multi
--------------------------------------------------------------------------------
blue tome 40 38 2 38 4
scroll folio 40 22 18 22 1
--------------------------------------------------------------------------------
TOTALS 80 60 20 60 5
================================================================================
...per-stacker contents...
SPELL STATISTICS (60 unique spells)
================================================================================
Spell Name Mana Total Locs
--------------------------------------------------------------------------------
Acid Splash Elemental 5 1
Heal Life 3 1
================================================================================
Multi counts sections holding more than one copy. Locs is how many separate sections a spell is spread across (more than one is a candidate for clean).
Pull a single copy of a spell into your hand, by full name or abbreviation (exact, case-insensitive). If the spell is spread across several sections, the smallest stack is drawn from first.
;stack-scrolls get <spell name or abbreviation>
Examples:
;stack-scrolls get Heal
;stack-scrolls get "Acid Splash"
;stack-scrolls get acidsplash
Use quotes around multi-word spell names. The scroll ends up in your hand, ready to read or use.
List only the scrolls of a given mana type.
;stack-scrolls mana <type>
Valid types: lunar, holy, life, arcane, ap, elemental.
Example:
;stack-scrolls mana life
The output matches the display format, filtered to that mana type.
Clear the cached stacker map and read every stacker fresh. Use this if you have added or removed scrolls by hand and the listings look stale.
;stack-scrolls reset
Remove scrolls you do not want to keep: anything filtered out by your keep and discard lists, plus any copies above max_scrolls_per_spell. Prune does not move or merge scrolls; it only removes.
;stack-scrolls prune # simulate: print the plan, change nothing
;stack-scrolls prune confirm # execute the plan
Simulation output:
================================================================================
PRUNE PLAN
================================================================================
UNWANTED SCROLLS (will be completely removed):
--------------------------------------------------------------------------------
Spell Stacker Count
--------------------------------------------------------------------------------
Frostbite blue tome 3
--------------------------------------------------------------------------------
Subtotal: 3 scroll(s) to remove
OVER LIMIT (max_scrolls_per_spell: 100):
--------------------------------------------------------------------------------
Spell Total Limit Excess
--------------------------------------------------------------------------------
Heal 150 100 50
->scroll folio 125 copies
->blue tome 25 copies
--------------------------------------------------------------------------------
Subtotal: 50 scroll(s) to remove (excess above limit)
================================================================================
SUMMARY
================================================================================
Scrolls to KEEP: 100 (1 spell types)
Scrolls to REMOVE: 53
- Unwanted: 3
- Over limit: 50
Slots to FREE: 1
================================================================================
This was a SIMULATION. No scrolls were removed.
To actually prune, run: ;stack-scrolls prune confirm
Over-limit trimming removes copies from the smallest stacks first, so a full 125-copy section is preserved where possible.
Pack your spells into as few stackers as possible so you can carry (or set aside) fewer stackers. Each spell is assigned to one target stacker, filling the stackers in the order you listed them, and scrolls are moved to match. Consolidate does not trash anything.
;stack-scrolls consolidate # simulate: print the plan, change nothing
;stack-scrolls consolidate confirm # execute the plan
Simulation output (abbreviated):
================================================================================
CONSOLIDATION PLAN
================================================================================
Total spell types: 60
Total scrolls: 437
Stackers needed after consolidation: 7 of 9
TARGET DISTRIBUTION:
--------------------------------------------------------------------------------
blue tome 40/40 slots
scroll folio 38/40 slots
swirled codex (empty after consolidation) <- can be removed
bamboo folder (empty after consolidation) <- can be removed
MOVES:
--------------------------------------------------------------------------------
Spell From To Count
--------------------------------------------------------------------------------
Acid Splash scroll folio hefty booklet 5
...
--------------------------------------------------------------------------------
Total scrolls to move: 437
Slots to free: 113
================================================================================
After consolidation, you can remove 2 stacker(s):
- swirled codex
- bamboo folder
================================================================================
This was a SIMULATION. No scrolls were moved.
To actually consolidate, run: ;stack-scrolls consolidate confirm
See Understanding consolidate for what happens when the stackers are very tightly packed.
Two jobs in one pass: merge duplicate sections of the same spell (copies of one spell spread across multiple sections are combined into a single stack), and remove unwanted scrolls per your keep and discard lists.
;stack-scrolls clean # simulate: print the plan, change nothing
;stack-scrolls clean confirm # execute (unwanted scrolls are trashed)
;stack-scrolls clean keep # simulate, but plan to stow unwanted, not trash
;stack-scrolls clean keep confirm # execute, stowing unwanted instead of trashing
The keep option changes only how unwanted scrolls are disposed of: stowed rather than trashed. The plan preview names exactly which scrolls will be merged and which removed:
================================================================================
CLEANING PLAN
================================================================================
UNWANTED SCROLLS (not in keep list or in discard list):
--------------------------------------------------------------------------------
Frostbite: 3 scroll(s) will be trashed
blue tome [slot 5]: 3
CONSOLIDATION (duplicate spell slots):
--------------------------------------------------------------------------------
Heal:
Total scrolls: 8
Locations: 2
scroll folio [slot 1]: 5 (TARGET)
blue tome [slot 12]: 3
================================================================================
This was a SIMULATION. No scrolls were changed.
To actually clean, run: ;stack-scrolls clean confirm
How clean differs from consolidate:
- clean merges duplicate stacks of the same spell into one section and removes unwanted scrolls. It does not try to empty whole stackers.
- consolidate repacks all spells into the fewest stackers so entire stackers become removable. It never trashes.
keep_scrolls and discard_scrolls decide which spells are kept when stacking, pruning, or cleaning.
Matching is exact against a spell's full name or its abbreviation, case-insensitive, with surrounding whitespace ignored. There is no substring matching, so Fire matches only the spell named or abbreviated "Fire", never "Fire Ball".
The rules, in order:
- If a spell matches
discard_scrolls, it is removed (blacklist wins). - Otherwise, if
keep_scrollsis empty, the spell is kept (keep everything). - Otherwise, the spell is kept only if it matches
keep_scrolls(whitelist); anything else is removed.
Examples:
| keep_scrolls | discard_scrolls | Result |
|---|---|---|
[] |
[] |
Keep every spell. |
[] |
[Frostbite] |
Keep everything except Frostbite. |
[Heal, Acid Splash] |
[] |
Keep only Heal and Acid Splash; remove all others. |
[Heal] |
[Heal] |
Remove Heal (discard wins over keep). |
Blank list entries are ignored, so an accidental empty line cannot match every scroll.
Two optional caps control how many copies you keep. Both are off unless set.
-
max_scrolls_per_spell: a global cap on the total copies of any one spell across all stackers. During stacking, a copy that would push the total to or past the cap is rejected. Duringprune, existing copies above the cap are trimmed. -
max_scrolls_per_slot: a cap on copies within a single section. A new copy is rejected only when every existing section for that spell is full AND there is no empty slot to start a fresh stack. In other words, a scroll is never turned away while a non-full or empty slot could still hold it.
The game itself caps a section at 125 copies, so max_scrolls_per_slot: 125 mirrors that hard ceiling.
Limits require the nested stack_scrolls: format; they are unavailable in the legacy format.
When a scroll passes your filters but the stackers cannot hold it (all sections full, no empty slot), trash_excess_scrolls decides what happens:
-
false(default): the scroll is stowed in yourstacker_container(or your default stow location). Nothing is destroyed. -
true: the scroll is trashed using yourworn_trashcanif configured.
The safe default means a full run never silently destroys a scroll you wanted to keep.
A scroll stacker holds a fixed number of sections (slots). Each section is dedicated to one spell and holds copies of it. Pushing a scroll into a stacker files it into the matching section automatically, creating a new section in an empty slot if the spell is not present yet.
The script identifies each loose scroll before filing it: it looks at labeled scrolls to read the spell name, and reads glyph scrolls that must be studied rather than merely looked at. Identified spells are matched against your keep, discard, and limit settings before anything is pushed.
Stacker contents are cached in memory so repeated listings are fast. Maintenance commands refresh the cache automatically; use reset to force a fresh read after handling scrolls manually.
consolidate computes a final distribution that always fits (unless you genuinely have more spell types than total slots, which it reports as an error), then moves scrolls into place in a capacity-aware order so a stacker is drained before it is asked to accept more.
When the stackers are very tightly packed, a few moves may not be orderable perfectly, and a target section can fill up mid-run before the sections meant to leave it have moved out. When that happens the affected scrolls are set aside safely: they are stowed, labeled and intact, never destroyed. The run reports how many were set aside and where, for example:
NOTE: Stackers are tightly packed, so a few moves may not fit on this
pass. Anything that does not fit is stowed safely, labeled and
intact, never destroyed (recovery steps are shown at the end).
...
Consolidation complete! Moved 427 scroll(s), freed 111 slot(s)
10 scroll(s) did not fit and are stowed safely in your haversack,
labeled and intact, nothing was destroyed.
To file them back into the stackers, run: ;stack-scrolls haversack
To recover set-aside scrolls, re-stack them with ;stack-scrolls <container> once the consolidation has freed space. Re-running consolidate alone will not pick them up, because it reads only what is inside the stackers, not loose scrolls in your pack. This situation is uncommon and only arises when your stackers are nearly full.
All settings live under stack_scrolls: unless noted as shared/top-level.
| Setting | Type | Default | Description |
|---|---|---|---|
stackers |
list | (required) | Stacker items, in fill order. |
stacker_container |
string | (default stow) | The single container your stackers live in, and where set-aside scrolls are stowed. |
keep_scrolls |
list |
[] (keep all) |
Whitelist; exact name or abbreviation. |
discard_scrolls |
list | [] |
Blacklist; exact name or abbreviation; wins over keep. |
trash_excess_scrolls |
boolean |
false (stow) |
Trash (true) or stow (false) scrolls that will not fit. |
max_scrolls_per_spell |
integer | (off) | Global cap on copies of one spell. |
max_scrolls_per_slot |
integer | (off) | Cap on copies per section (game max 125). |
log_statistics |
boolean | false |
Write a timestamped per-run stats log. |
worn_trashcan |
string | (none) | SHARED top-level: worn trash receptacle for trashing. |
worn_trashcan_verb |
string | (none) | SHARED top-level: verb to empty the receptacle. |
Older configurations used top-level keys (scroll_stackers, stacker_container, keep_scrolls, discard_scrolls, trash_excess_scrolls). The script still reads these and prints a migration guide on startup, but the newer features (copy limits, statistics) require the nested format.
To migrate, move your keys under a stack_scrolls: block and rename scroll_stackers to stackers:
# OLD (still works, prints a deprecation notice)
scroll_stackers:
- scroll folio
stacker_container: haversack
discard_scrolls:
- Frostbite
# NEW (recommended)
stack_scrolls:
stackers:
- scroll folio
stacker_container: haversack
discard_scrolls:
- FrostbiteLeave worn_trashcan and worn_trashcan_verb at the top level; they are shared with other scripts and are not part of the stack_scrolls: block.
| Command | What it does |
|---|---|
;stack-scrolls <container> |
File every scroll in the container into your stackers. |
;stack-scrolls |
List all stacked spells with counts and locations. |
;stack-scrolls summary |
Verbose per-stacker and per-spell overview with mana types. |
;stack-scrolls get <spell> |
Pull one copy of a spell (name or abbreviation) into your hand. |
;stack-scrolls mana <type> |
List scrolls of one mana type (lunar, holy, life, arcane, ap, elemental). |
;stack-scrolls reset |
Clear the cache and re-read all stackers. |
;stack-scrolls prune [confirm] |
Remove unwanted and over-limit scrolls (simulate without confirm). |
;stack-scrolls consolidate [confirm] |
Repack spells into the fewest stackers (simulate without confirm). |
;stack-scrolls clean [keep] [confirm] |
Merge duplicate stacks and remove unwanted scrolls (simulate without confirm; keep stows instead of trashing). |
-
"No scroll stacker settings found" or "No scroll stackers defined." Your YAML is missing the
stack_scrolls:block or itsstackers:list. See YAML Configuration. - A deprecation notice prints on startup. You are on the legacy top-level format. It still works; see Migrating from the Legacy Format to unlock limits and stats.
-
Listings look out of date. Run
;stack-scrolls resetto re-read your stackers after adding or removing scrolls by hand. -
getsays no scroll found. Matching is exact on name or abbreviation. Check the spelling, quote multi-word names, or run;stack-scrollsto see exactly what is stacked. -
consolidate left some scrolls stowed. Your stackers were nearly full. The scrolls are safe in your container; re-stack them with
;stack-scrolls <container>once space is free. See Understanding consolidate. -
Scrolls are being trashed and you did not expect it. Check
discard_scrolls, a non-emptykeep_scrolls(which removes everything not listed),trash_excess_scrolls: true, andmax_scrolls_per_spell. Every removal command simulates first, so run it withoutconfirmto preview.