Skip to content

Documentation for stack scrolls.lic

Mahtra edited this page Jul 27, 2026 · 2 revisions

Stack-Scrolls (v3.1.2)

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.


Table of Contents


Requirements

Software

  • Lich5 with the dr-scripts dependency installed and up to date.
  • The bundled spells data (ships with dr-scripts). It supplies spell abbreviations and mana types, used by get, the mana filter, and the abbreviations shown in listings. The script still runs without it; those features degrade gracefully.

In-Game

  • 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 (see stacker_container).

YAML

At minimum you must define your stackers under a stack_scrolls: block. See YAML Configuration.


Quick Start

  1. Add a stack_scrolls: block to your character YAML listing your stackers:

    stack_scrolls:
      stackers:
        - scroll folio
        - blue tome
      stacker_container: haversack
  2. Drop the loose scrolls you want to file into a container (for example your haversack).

  3. Run the stacker over that container:

    ;stack-scrolls haversack
    
  4. Check what you have:

    ;stack-scrolls
    

That is the whole loop. The maintenance commands below (prune, consolidate, clean) are optional housekeeping you run occasionally.


YAML Configuration

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: dump

Notes:

  • stackers values are whatever you would type after get my .... If a plain noun is ambiguous, use Lich dot notation to disambiguate, for example scroll.folio or abyssal-black.codex.
  • The order of stackers matters for consolidate: it fills the first stacker, then the second, and so on, so the later ones can be emptied and removed.
  • worn_trashcan and worn_trashcan_verb control periodic emptying of a worn trash bin while trashing. They are optional and shared with other scripts.

Commands

All commands are prefixed with ;stack-scrolls. Commands that change anything (prune, consolidate, clean) only simulate until you add confirm.

Stack loose scrolls (default)

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
------------------------------------------------------------
============================================================

display (no arguments)

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).

summary

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).

get

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.

mana

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.

reset

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

prune

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.

consolidate

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.

clean

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 and Discard Filtering

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:

  1. If a spell matches discard_scrolls, it is removed (blacklist wins).
  2. Otherwise, if keep_scrolls is empty, the spell is kept (keep everything).
  3. 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.


Copy Limits

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. During prune, 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.


Excess Scrolls: Stow or Trash

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 your stacker_container (or your default stow location). Nothing is destroyed.
  • true: the scroll is trashed using your worn_trashcan if configured.

The safe default means a full run never silently destroys a scroll you wanted to keep.


How Stacking Works

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.


Understanding consolidate

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.


Settings Reference

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.

Migrating from the Legacy Format

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:
    - Frostbite

Leave 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 Quick Reference

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).

Troubleshooting

  • "No scroll stacker settings found" or "No scroll stackers defined." Your YAML is missing the stack_scrolls: block or its stackers: 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 reset to re-read your stackers after adding or removing scrolls by hand.
  • get says no scroll found. Matching is exact on name or abbreviation. Check the spelling, quote multi-word names, or run ;stack-scrolls to 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-empty keep_scrolls (which removes everything not listed), trash_excess_scrolls: true, and max_scrolls_per_spell. Every removal command simulates first, so run it without confirm to preview.

Clone this wiki locally