Token edition selection improvements (filter, era-match, per-game pinning) and 55 new token registrations#10518
Open
vanja-ivancevic wants to merge 11 commits intoCard-Forge:masterfrom
Open
Token edition selection improvements (filter, era-match, per-game pinning) and 55 new token registrations#10518vanja-ivancevic wants to merge 11 commits intoCard-Forge:masterfrom
vanja-ivancevic wants to merge 11 commits intoCard-Forge:masterfrom
Conversation
Contributor
vanja-ivancevic
commented
Apr 25, 2026
- Adds adventure-mode token edition filter respecting per-plane allowedEditions and restrictedEditions, with optional restrictedTokens for blocking specific EDITION/script pairs
- Adds per-user setting "pick token art from edition closest to producing card's release date" (off by default, no impact on vanilla Forge)
- Pins token edition per game so duplicates of the same script share art within a single match
- Adds runtime consultation of token-images.txt URL map for hosted token downloads
- Crops rounded-border fringe on token images via ImageCache (parity with regular cards)
- Fixes Unglued token collector numbers to match Scryfall TUGL
- Adds Magic Player Rewards 2002 (PR2) and Duelist Magazine (TDLS) edition files
- Adds 6 MicroProse 1997 tokens to PAST (Astral Cards): Wasp, Djinn, Tetravite, Poison Snake, Spawn of Azar, Rukh
- Adds Old Border Custom (OBC) edition with 49 Card Conjurer renders covering token coverage gaps for Old Border legal cards
- Wires Shandalar Old Border config to use the filter, allow PAST/UGL/MPR/PR2/P03/TDLS/OBC, and block 2 modern-frame P03 entries
Unglued tokens in the edition file were numbered 1-6, but Scryfall
indexes them under the TUGL set at collector numbers 89-94. Forge builds
token image URLs as {tokensCode}/{collectorNumber}/en, so tugl/1..6 was
404ing and Unglued token art was silently unreachable.
Renumber the six [tokens] entries (Pegasus, Soldier, Zombie, Goblin,
Sheep, Squirrel) to their real TUGL collector numbers so Scryfall
lookups resolve.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
croppedBorderImage gated the 0.96x scale-crop on filenames containing .fullborder., which is how regular card images are named. Token images live under pics/tokens/ and do not carry that substring, so in Crop UI mask they were drawn at full extent and the printed card's rounded corners bled through as white fringes at all four corners. Extend the condition to also trigger the crop when the image path contains "tokens", matching the same marker ImageCache already uses to treat token art as fullborder for border-color and radius tracking. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…dEditions Add a Predicate<CardEdition> slot on TokenDb with a setter (setDefaultEditionFilter), mirroring CardDb.setCardArtPreference. Expose the filter via a new ITokenDatabase method getTokenFromEditions(name, Predicate<CardEdition>) that parallels the existing getCardFromEditions(name, ..., Predicate<PaperCard>) on the card side. fallbackToken delegates to it. With no filter installed, fallbackToken keeps its historical behavior (first alphabetical edition that registers the token wins). With a filter, it picks a random legal edition, or returns null if none of them register the token, letting Forge's no-art placeholder path handle rendering rather than quietly falling back to a non-legal printing. Adventure Config.loadResources pushes a filter built from the plane's allowedEditions and restrictedEditions on plane entry, so token art in Old Border is limited to the same set pool that already gates cards. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When the edition filter yields multiple legal editions for a token script, fallbackToken rolls a random one on each call, so two summons of the same token type in one game could land on different arts. Add a WeakHashMap<Game, Map<script, edition>> on TokenInfo so the first resolution pins the edition and later calls in the same game reuse it. Weak keys let finished games be garbage-collected. No effect when the filter is unset, since unfiltered fallbackToken is already deterministic. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…era-matched art
Two related refinements to TokenDb.getTokenFromEditions / fallbackToken:
1. restrictedTokenEntries: a set of "{EDITION_CODE}/{tokenScript}" pairs
that are skipped during fallback, so a plane can block individual
printings within an otherwise-legal edition. Adventure planes populate
it from a new restrictedTokens field on ConfigData, alongside the
existing allowedEditions / restrictedEditions.
2. preferEraMatchedArt: when true and the host card's edition release
date is known, fallback picks the legal edition whose release date is
closest to the host's, deterministically. fallbackToken now accepts
the host edition code so TokenDb can look up the date. Exposed as a
user-level adventure setting (SettingData.preferEraMatchedTokenArt)
with a checkbox in SettingsScene; default off, so vanilla behavior is
preserved.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The same "filename URL" list the bulk image downloader reads (token-images.txt) is now consulted by ImageFetcher's token branch, so modders can route token art to hosted URLs without a new mechanism (parallel to how booster-images.txt works). The override URL is added to the download list; if none matches, falls through to the existing Scryfall path. For custom or unknown editions (no Scryfall record), a hit in the override list is enough to trigger the download. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PR2 (Magic Player Rewards 2002): 6 old-frame paper tokens (Squirrel, Zombie, Elephant, Wurm, Dragon, Soldier) registered at Scryfall collector numbers 3-8. Scryfall-fetchable via the standard token URL path, no image hosting needed. TDLS (Duelist Magazine Tokens): 5 custom renders of the 1995 Duelist Card-Forge#4 token insert (Thrull, Saproling, Citizen, Camarid, Goblin). Not on Scryfall; images are hosted separately and routed via token-images.txt. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Five lines mapping the Forge local-cache filenames for Duelist Magazine
tokens (TDLS/N_{script}.jpg) to their hosted URLs on oldborder-shandalar.net.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…e P03 entries Add MPR, PR2, P03, TDLS to allowedEditions so the token filter can pick Magic Player Rewards 2001-2003 and Duelist Magazine prints in addition to Unglued. Block P03/r_4_4_bird_flying (Rukh) and P03/b_x_x_demon_flying (Demon) via the new restrictedTokens field: both are post-2003 modern-frame tokens that happen to share the P03 Scryfall set code with the genuinely old-frame P03 tokens. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PAST (Astral Cards, MicroProse Shandalar 1997) gains 6 token entries (cnums 13-18): Wasp, Djinn of the Bottle, Tetravite, Poison Snake, Spawn of Azar, and Rukh. These cover tokens produced by The Hive, Bottle of Suleiman, Whimsy, Tetravus, Serpent Generator, Necropolis of Azar, and Rukh Egg (replacing the restricted modern-frame P03 Rukh). OBC (Old Border Custom Tokens) is a new edition holding 49 Card Conjurer TokenOld renders for scripts with no legal old-border printing. Dated 2003-05-26 (end of Old Border era) since most of these scripts only appear here. Added to allowedEditions. Images are hosted on oldborder-shandalar.net and wired via token-images.txt URL overrides. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…tions overloads The single-arg `fallbackToken(name)` and `getTokenFromEditions(name, filter)` overloads were added by earlier commits on this branch but ended up with no callers — `getToken` always uses the two-arg `fallbackToken(name, edition)`, which routes through the three-arg `getTokenFromEditions(name, filter, hostDate)`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.