Perfected Theory (FRA) - #11745
Merged
Merged
Conversation
tool4ever
reviewed
Aug 31, 2026
tool4ever
approved these changes
Aug 31, 2026
delebedev
added a commit
to delebedev/forge
that referenced
this pull request
Sep 5, 2026
* Add Assualt Drone (Card-Forge#11562) * [maven-release-plugin] prepare release forge-2.0.14 * [maven-release-plugin] prepare for next development iteration * Restore POM files for preparation of next release * Restore pom files * Migrate hobbit script files * Realm of legends 1.067: Several small deckfixes; metalworker unban (Card-Forge#11570) * Unbanned metalworker * Deckfix * Fixed Arzakon drop * iOS: implement exit()/restart() as process termination Review feedback on Card-Forge#11190 (Jetz72): the return-to-main-menu intercept prevented restart-required settings (Adventure plane, skin, language, card DB toggles) from ever taking effect — process-lifetime singletons can only be rebuilt by a fresh launch. Forge iOS is sideload/TestFlight distributed, so Apple's no-programmatic-exit HIG concern doesn't apply; exit the process and let the user relaunch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * iOS: fix oversized in-game buttons on iPhone (HdpiMode.Pixels) Follow-up to Card-Forge#11190 review: the prompt OK/Cancel buttons covered 87% of an iPhone's width (13.4% of height, pinned at forge.util.Utils's max clamp) vs ~56%/8.3% on a comparable Android phone. Root cause is a points-vs-pixels unit mismatch in the default HdpiMode.Logical: sizes come from getWidth/getHeight (logical points) but density from getPpcX/getPpcY (physical px/cm), inflating the 1.1cm finger size by the retina scale. Pixels mode makes both physical pixels — the exact units Android reports. Phones only; iPad layout is device-verified and stays on Logical. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Sound: split iOS Music-backed effects into MusicAudioClip Review feedback on Card-Forge#11190 (Jetz72): replace the per-method isIOS branches in the mobile AudioClip with a second IAudioClip implementation. AudioClip is back to a pure OpenAL Sound impl; the AVAudioPlayer/clock-domain logic moves verbatim to MusicAudioClip; the createClip factories pick the implementation per call. Behavior-neutral on every platform. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * iOS: ship an app icon via an Assets.xcassets catalog Follow-up to Card-Forge#11190 review: the unsigned IPA contained zero icon data — the robovm.xml/Info.plist entries pointed at Icon*.png files that were never committed (silently dropped by a contributor-global '*.png' gitignore rule), so sideloaded installs show the generic placeholder. Commit an AppIcon asset catalog (1024px, opaque, from the Android launcher artwork's framing) under forge-gui-ios/resources/; RoboVM 2.3.24 compiles *.xcassets resources with actool and merges the generated CFBundleIcons/CFBundleIconName into Info.plist, so no build changes are needed. Delete the dead legacy CFBundleIcons block and add a .gitignore negation so global '*.png' excludes can't drop iOS icons again. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * GUI: convert shared form-factor checks to GuiBase.isMobile() Review feedback on Card-Forge#11190 (Jetz72); builds on the isMobile() helper from Card-Forge#11382, converting the remaining sites where Android and iOS provably want the same behavior: adventure data paths (Config, World), fallback-skin title/transition textures (Assets), hardware-cursor skip (Forge.setCursor), hover detection (FDisplayObject), battlefield-hover gamepad gate (MatchScreen), PID logging (NetworkLogWriter). Behavior-neutral by construction: isMobile() == isAndroid() on Android and == false on desktop; only iOS changes, and each converted site was individually audited. Sites where isAndroid()/isIOS() gate genuine platform machinery (APK updates, audio backend selection, orientation handling) intentionally keep the specific check; a follow-up will tackle the behavior-changing sites (touchpad mode, tooltips, on-screen keyboard) after device verification. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * iOS/mobile: remove RGB565 downgrade for card textures; use RGBA8888 everywhere RGB565 was applied to both bundled cards (getCardTextureFilter) and downloaded Scryfall images (downscaleCardPixmap) on iOS to reduce native memory. Measured peak physical footprint is 1.9 GB in both cases (sim-verified), well within the jetsam ceiling on 4 GB devices with the existing post-load GC in place. Remove getCardTextureFilter() entirely — it was an iOS-only wrapper that now just delegates to getTextureFilter(). Callers use getTextureFilter() directly. downscaleCardPixmap still caps resolution at MAX_CARD_TEX_DIM but no longer converts to RGB565. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * net: narrow ProcessHandle PID catch to Exception (Copilot Card-Forge#11190) catch (Throwable t) here would also swallow fatal Errors (OutOfMemoryError). ProcessHandle is desktop-only (guarded by !isMobile), so a plain Exception catch is sufficient for the never-expected failure; the comment was also stale (referenced the mobile jvmdg path this desktop branch never runs). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * iOS: show the real app version instead of hardcoded "0.0" The mobile splash/home version came from the iOS IDeviceAdapter.getVersionString() override, which was a hardcoded `return "0.0"`. RoboVM AOT-links into one binary with no runtime JAR manifest, so BuildInfo.getVersionString() (manifest Implementation-Version) resolves to "GIT" on iOS — the desktop/Android path doesn't work here. Read the app bundle's own version via NSBundle instead (the iOS analog of Android's PackageManager versionName), the same API already used for the CFBundleVersion cache-buster: shows "<CFBundleShortVersionString> (<CFBundleVersion>)". Also un-stale the marketing version (app.version was frozen at 1.0) to the pom versionCode so it reads 2.0.14. Sim-verified: splash shows "v.2.0.14 (1)" on iPad and iPhone. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * iOS: load downloaded card images through the AssetManager, not a bypass Review feedback on Card-Forge#11190 (Jetz72): the iOS downloaded-image path bypassed the AssetManager and reimplemented its responsibilities in a set of platform-specific branches in ImageCache. Move it back in: a small custom TextureData (CardTextureData) does the java.io byte read + downscale and is handed to the manager via TextureParameter.textureData — the stock TextureLoader honours a preset textureData and ignores the FileHandle, so the read stays a plain byte read (iOS can't reliably load a FileHandle from Documents) while the AssetManager owns the whole lifecycle: get/load/unload/dispose/context-loss reload/memory-tracking. Deletes the three parallel structures (pixmapCache, the downloadedTextureCache LRU, textureToPath), the isDownloadedImage bypass branch, and the toRelativePath rewriting. loadAsset/getAsset now take the same manager path on every platform; the one residual iOS check just selects the decode parameter. No custom loader / setLoader, so skins, fonts, avatars and other textures are untouched. The old 48/120 downloaded ceiling moves into the unified iOS card cap so the resident set still plateaus. Border keying derives from the manager-owned TextureData (aligns store==lookup, fixing a Windows desktop-wrapper backslash mismatch). Sim-verified on iPad + iPhone: cards render, borders correct, ~1.9 GB peak (unchanged). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Clean up * iOS: force-link the Xalan output serializer so XML saves work Every XmlUtil.saveDocument() call failed on device with "WrappedRuntimeException: org.apache.xml.serializer.ToXMLStream" — achievements plus the card, deck and item-view preference writers, so none of them persisted. Xalan picks its serializer by name: SerializerFactory reads the class from org/apache/xml/serializer/output_{xml,html,text}.properties and Class.forName()s it, which the tree-shaker can't see. The classes and those properties are both present in the RoboVM runtime, so linking the package is all that's needed; robovm.xml already force-links the transformer factory but not the serializer. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Net lobby: stop per-keystroke CHANGE events and team-selection echo Card-Forge#11190 made FTextField fire its CHANGE handler on every keystroke so search fields can live-filter. Consumers that treat CHANGE as a committed value broke in multiplayer: the online and in-match chats send one network message per typed character (and the send handler clears the field, so every letter became its own chat line), and the lobby name field commits per keystroke — a prefs.save() plus a full slot-state broadcast per character. CHANGE is now commit-only unless a field opts in via setLiveChangeEvents(true). Every local-only filter opts in, so live filtering is unchanged where it was intended: the item-manager card/deck search, the settings and card-image-browser searches, the entity picker, the list chooser, the auto-yields filter and the file chooser's filename field. The three consumers that treat CHANGE as committed — both chat fields and the lobby name — are the ones that become commit-only. FComboBox/FToggleSwitch/FSpinner raise CHANGE from their own code and are unaffected. Independently, FComboBox fires its changed handler for programmatic selection, so a lobby broadcast that changes any panel's team re-enters teamChangedHandler on every OTHER client for a panel that client does not own. The wire listener drops the panel index and the server applies client updates to the sender's own slot, so the echo rewrites the echoing client's own team: with three or more connected players any team change cascades until the lobby converges onto one team. The handler now ignores events for panels the client may not edit and events raised by the network-apply path (setTeam/setArchenemyTeam), and setPlayerName no longer clobbers a field that is mid-edit. Verified with three simulators (host + two guests, iOS 18.4) joined over loopback: typing a 5-character word then Enter produces exactly one chat message on all three clients (was five), and moving one guest between teams leaves the host's and the other guest's teams untouched instead of converging. Card search re-checked in the deck editor: typing filters live (95084 -> 374 with no Enter) and backspace re-widens it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Fix iOS text-field backspace deleting two characters at once A hardware-keyboard backspace inside a text field arrived on two paths and each deleted a character: the queued keyDown(Keys.BACKSPACE), and keyTyped('\b') from gdx's invisible-UITextField delegate (the same delegate the software keyboard uses). gdx's iOS backend suppresses its OWN queued KEY_TYPED while that field is active, but not the keyDown, so the two survivors both ran — confirmed on the simulator: one press logged down 67 + typed 8 in the same frame and removed two chars. iOS-gate the keyDown branch so the keyTyped path performs the single deletion whichever keyboard sent it; the software keyboard (keyTyped only, no keyDown) is unchanged, and desktop/Android (keyDown only) keep their path. Also fire CHANGE from the keyDown delete under liveChangeEvents, matching the keyTyped branch, so on desktop/Android a live search filter refreshes while deleting instead of only while typing. Verified: iOS one press -> one delete + list re-filters (374->1153); Android one press -> one delete + count refreshes (via keyDown, gated path unused there). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Update nighthowl_pursuer.txt Closes Card-Forge#11569 * Star Trek Welcome Decks, batch 2 (Card-Forge#11549) * Add Defense force aggressor (Card-Forge#11567) * Add Organic Avulsion Unit (Card-Forge#11566) * Create massimo_the_magician.txt (Card-Forge#11546) * Prep for Isolated Hut map * Prep for Isolated Hut map - everything but adding to map because I want to do that all at once with the other new areas * An-Havva Inn mapfile * Add Head of Security (Card-Forge#11575) * Add Talarian Hook Spider (Card-Forge#11576) * Yume, Chronicler of Valor (MBC) (Card-Forge#11538) * Itazura, Lingering Wick (MBC) (Card-Forge#11545) * Head of Security fix (Card-Forge#11579) * Star Trek Welcome Decks, batch 3 (Card-Forge#11557) * Sync missing keys from en-US.properties to all other language files. * Fix typo in trigger limit from 'ResolveLimit' to 'ResolvedLimit' * An-Havva Inn mapfile fix attempt * Autumn willow deck * Feroz and Joven and chandler decks, removed an-zerrin ruins from banlist * Greensleeves deck * Daughter of Autumn deck * Ann-havva inn finishing touches save for adding it to the map * Banned and Restricted Announcement for August 10, 2026 * Star Trek Welcome Decks, batch 4 (Card-Forge#11571) * Deckfix * Deckfix * Update loyalty ability for Thomil the Destroyer * iOS pipeline: self-recovering simulator builds (Card-Forge#11588) RoboVM's ipad-sim mojo launches the app after the AOT link and blocks in SimLauncherProcess.waitFor until the app quits — and on Apple Silicon it picks its own simulator, so every scripted sim build hung at the launch step and needed the wedged maven process killed by hand. All the pipeline needs from the mojo there is target/robovm.tmp/config.xml, written once the link is done: run the mojo in its own process group, stop it when config.xml lands (test -s plus a settle sleep — the mojo opens the file before serializing into it), and let assemble_arm64_sim_app rebundle with the standalone AppCompiler (the AOT cache is content-hashed, so nothing recompiles). --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * Update cardnames translations * Opposing directions now cancel each other out on keyboard Added helper function to KeyBinding.java for getting pressed key from libGDX * Edition updates: SLD, TRC, TRK * Hatsune Miku Precon * Update lake_town_mariners_gone_fishing.txt * Nephilim epochal enemy * Ancient Opal Cavern Map * Custom hobbit precon * Fixed typo in miku precon * Added UB shops * UB Shopfile sign updates * Otherworldly market map * Otherworldly market update * Otherworldly market update again, high perfect morcant deck * Zoom card when tapping on cardView on the stack (Card-Forge#11594) * Zoom card when tapping on cardView on the stack * update check * Update dyfed_the_guiding_hand.txt * Fix CardType.getSortedSubTypes init race + duplicate entries getSortedSubTypes assigned the static field first and then sorted it in place, so two threads racing the first-time lazy init could mutate the list mid-sort and trip TimSort's "Comparison method violates its general contract" IllegalArgumentException. Build a TreeSet locally and publish an ImmutableList: the copy is complete before any caller can see it (and ImmutableList's final fields make the unsynchronized publish safe), no locking needed. The TreeSet also drops duplicate entries — some types appear in two sections (e.g. Spacecraft), which previously showed up twice in the Advanced Search subtype list. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Update dyfed_the_guiding_hand.txt (Card-Forge#11599) * Fix valid card type from 'Land' to 'Mountain' * More decklists for eclipsed court * Fix unselectable tokens after game 1 of a match (Card-Forge#11592) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Another decklist; cut enchanted evening from enemies with archon to avoid infinite loop * Revert "Feature/11167: Revamped input handling + better road detection" * Last 2 eclipsed court decks, eclipsed court items * Finishing eclipsed elven court dungeon * Clean up (Card-Forge#11609) * Update CardImageRenderer for Prepare Cards (Card-Forge#11607) * Add Time Spiral Remastered(TSR) Rankings based on draftsim rankings. * Fix CardImageRenderer - closes Card-Forge#10038 * Ashling's Domain dungeon with all decks * Update getaway_barrel.txt * LibGDX Update 1.14.2 (Card-Forge#11606) * LibGDX Update 1.14.2 * Update ios-pipeline.sh * Fix DefaultAndroidInput delta reset libgdx/libgdx#7838 --------- Co-authored-by: tool4ever <therealtoolkit@hotmail.com> * Fix custom cards messing things up (Card-Forge#11615) * Change card type to Legendary Artifact Equipment * Update bolg_of_the_north.txt * Mapfix * Idyllic Beachfront, everything but enemies * Finishing Idyllic Beachfront * Peaceful clearing everything but decklists and enemies, adding new dungeons to map * Move hardcoded Adventure Mode strings to language files * Update de-DE.properties * Update fr-FR.properties * Update it-IT.properties * Update ja-JP.properties * Update pt-BR.properties * Update zh-CN.properties * Update ru-RU.properties * Update ko-KR.properties * Update valid card ownership in nether_traitor.txt * Update manifest dread effect to trigger twice * Edition updates: SLD * Some Card Updates/Fixes (Card-Forge#11624) * CardState: cache LandMana and copy them for LKI * Peaceful clearing finished * Fix Navigation Arrow position (Card-Forge#11626) - adjust navigation arrow pointing from left most bottom to center of POI - use nearest POI position from player center position * Update slight_malfunction.txt * Fix AI X sizing that left Curse of the Swine and Distorting Wake uncastable (Card-Forge#11338) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * Planeswalker dueling club map * Alpha testing fixes * Fix Dungeon Art render * Fix QuestLogScene Track Button Listener * Use Indicator for Quest Stages * Fix variant colors (Card-Forge#11630) * Added support for igd v2 gateways and multi-device upnp discovery (Card-Forge#11317) * Update garruk_veiled_butcher.txt * Fix for broken enemy deck (Card-Forge#11632) * Implement Beam me up and Marooned's restriction on it (Card-Forge#11589) (Card-Forge#11633) * Implement Beam me up and the Marooned restriction on it (Card-Forge#11589) Beam me up <Cost> is Flashback with one extra mandatory cost: cast from your graveyard for <Cost> if you also return a creature you control to its owner's hand, then exile the spell. It reuses the existing graveyard-cast machinery - getGraveyardSpellByKeyword, which Flashback, Harmonize and Mayhem already share, plus the same "exile as it leaves the stack" replacement Flashback installs. The return is appended to the cost in GameActionUtil rather than written into each card script's keyword cost. Harmonize already adds its extra cost there, and keeping it out of the script means the printed cost stays {2}{U} rather than growing a Return clause, and no script has to repeat the wording. Marooned's "can't be beamed up" has no keyword on the card, so it travels as a granted keyword string, the way "doesn't untap during your untap step" does. The restriction then rides on the appended cost's valid string: Return<1/Creature.YouCtrl+canBeBeamedUp/creature you control> so a permanent that can't be beamed up simply isn't a legal way to pay, and both the human and the AI paths honour it without extra code - CostReturn already filters candidates by that string. Wording for both cards is taken from Scryfall spoilers; TRK is dated 2026-11-13 and these are the only two cards in the set that touch the mechanic so far. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Fold the three graveyard-cast keywords into one branch Beam me up's exile replacement was a third verbatim copy of Flashback's and Harmonize's. The three bodies were identical apart from the name shown in the description and the SpellAbility property the stack check matches on, so they are now one branch that picks those two strings up front. Harmonize had no test coverage, and the Flashback test that does exist checks whether the graveyard cast is offered - which comes from GameActionUtil, not from this code. Added a test that reads the ValidStackSa off each of the three keywords' replacement, since a swapped name or property is exactly what folding them together could get wrong and nothing else would have caught it. This commit is separable: drop it and the mechanic in the previous commit stands on its own. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Update marooned.txt * Carry "can't be beamed up" as a static rather than a granted keyword Review preference: @tool4ever asked for a hidden keyword instead of a printed one and @Hanmac for a static if possible. The static is the better of the two - it is how every other "can't be X" restriction in the engine works, and it lets any card grant this without inventing keyword text for the affected permanent to carry. Adds StaticAbilityMode.CantBeBeamedUp and a StaticAbilityCantBeBeamedUp modelled on StaticAbilityCantRegenerate. Marooned's line becomes S:Mode$ CantBeBeamedUp | ValidCard$ Permanent.EnchantedBy | Secondary$ True matching the other aura-borne Cant statics, which mark the duplicate description Secondary rather than printing the sentence twice. The cost's valid string is unchanged, so CardProperty is the only caller that had to move. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Drop the description a Secondary static never prints Card.java skips isSecondary() statics when it builds the ability text, so the sentence was carried twice in the script and shown once. The R: line above it is the one that prints. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: liamiak <liamiak1@gmail.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: tool4ever <therealtoolkit@hotmail.com> Co-authored-by: Agetian <stavdev@mail.ru> * Fix for broken map * Improve clue effects * Some cleanup (Card-Forge#11642) * Implement charset fallback for ZipFile creation (Card-Forge#11640) Added a fallback mechanism for charset selection in ZipFile creation to fix an unhandled exception on iOS. * Use card art for prepared spell (Card-Forge#11641) * Use card art for prepared spell * prevent NPE * Update adventure logo and backgrounds (Card-Forge#11645) * Update adventure backgrounds * Update adventure deckbox to pixelart * fix inverted texture region image * update adventure logo and repeating texture * update items.png sprite for the adventure logos * update remaining images to pixel art * Enable ChangeZone in MayEffectFromOpeningDeck; update un-card list. (Card-Forge#10740) * Storied: add Effect Image * Oracle view mobile (Card-Forge#11399) * Add Oracle text view on mobile * Deprecated fix * Add tooltip info (Card-Forge#11650) * Add tooltip info * update renders for tooltipinfo * Fix/11167: Revamped input handling Android fix (Card-Forge#11647) * Attempting to fix input Everything works for the player animations are jittery on controller now. haven't tested mobile either but mouse works. (cherry picked from commit f28811a) * Fixed controller jitter. Still not tested on mobile but will do later. (Should be the same as mouse input) (cherry picked from commit b260851) * Cleanup of GameStage.java (cherry picked from commit 467ab52) * Mirroring changes from Card-Forge#11167 (cherry picked from commit 82714d1) * Opposing directions now cancel each other out on keyboard Added helper function to KeyBinding.java for getting pressed key from libGDX (cherry picked from commit a631d4f) * Added additional input method for Android devices for touchKnob * Urgent Necropsy: fix missing planeswalker part Closes Card-Forge#11649 * Fix tooltipInfo visibility onImageFetched * Fix RewardActor newOverlayGestureListener (Card-Forge#11652) * Fix RewardActor newOverlayGestureListener * update check and remove unnecessary code * cleanup * Enhance holdtooltip View (Card-Forge#11653) * Enhance holdtooltip View * add backdrop for CardPack tooltip description * Update adventure splash logo (Card-Forge#11656) * Update fireminds_foresight.txt (Card-Forge#11658) * Make Adventure action animations frame-aware (Card-Forge#11492) * Adventure: Make action animation timing frame-aware * Adventure: Harden frame-aware animation playback * Adventure: Cap action animation waits * Adventure: Limit death animations to three seconds * fix rewardpack backdrop position * update cBackDrop reference position * Changes * CardFactoryUtil: use AbilityStatic for Ascend * Refactor AiCardMemory (Card-Forge#11667) * Include previously missing shard when fetching lands (Card-Forge#11673) * - Add puzzle PS_HOB1. (Card-Forge#11674) * move isTurnFaceUp to getAllPossibleAbilities (Card-Forge#11654) * move isTurnFaceUp to getAllPossibleAbilities * Fix simulation gap * Finish comment * Remove obsolete check --------- Co-authored-by: tool4EvEr <tool4EvEr@> * Improve AI handling of storage lands (Card-Forge#11672) * Improve AI handling of storage lands * Harden storage land AI payoff planning * Streamline storage land AI coverage * Respect mana rules in storage land planning * Simplify storage land AI handling * Delete forge-gui-desktop/src/test/java/forge/ai/ability/StorageLandAiTest.java --------- Co-authored-by: tool4ever <therealtoolkit@hotmail.com> Co-authored-by: Agetian <stavdev@mail.ru> * Fix NPE (Card-Forge#11683) * Edition updates: PSPL, PZ2, SLD, SLZ, YMKM * Don't create token copies that just die (Card-Forge#11690) * Don't create token copies that just die * Don't create token copies that just die --------- Co-authored-by: tool4EvEr <tool4EvEr@> * Add Japanese translations for Dominaria United (Card-Forge#11666) * Replace a racy FCollection test with a deterministic one (Card-Forge#11677) testCompletableFuture removes the same collection from four threads at once and asserts the resulting size. That held when it was written (0854fbb), where FCollection guarded every mutator with an explicit lock. Card-Forge#6657 replaced that lock with Collections.synchronized wrappers, which cannot make remove's two-collection update atomic, and b858b48 dropped the wrappers once threadSafeIterable was restored to handle iteration. Concurrent removes have raced ever since. Test what threadSafeIterable actually guarantees instead: the snapshot lets a loop remove from the collection it is iterating without throwing or skipping an element. Co-authored-by: liamiak <liamiak1@gmail.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> * Add missing Lesson keyword to Yip Yip! (Card-Forge#11696) * Restore longpress for Reward Actor (Card-Forge#11699) * RewardActor - add longPress listener for holdtooltip * update check * Minor cleanup * Update hulkling_young_avenger.txt * Realm of legends 1.071: Handful of minor deck and mapfixes (Card-Forge#11703) * Deckfix * Mapfix, a few deckfixes * Add Japanese translations for five sets (Card-Forge#11691) * Fix AI cloning creatures that shrink under its own control (Card-Forge#11675) Co-authored-by: Claude Opus 5 <noreply@anthropic.com> * Edition updates: SLD, SLZ * Fix Nori, Teller of Tales (Card-Forge#11713) * Add Japanese translations for OTJ, BLB, and ONE (Card-Forge#11711) * Fix CON -> CFX * Keep the game running when delta collection hits a concurrent change (Card-Forge#11723) Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> * Clean up (Card-Forge#11726) * Edition updates: PMEI, SLD, SLZ * StaticAbilityManaRestriction: better ability for Myr Superion (Card-Forge#11700) * StaticAbilityManaRestriction: better ability for Myr Superion * remove special None case * Update StaticAbilityManaRestriction.java Restrict to just getHostCard * Update StaticAbilityManaRestriction.java fix import * remove ValidSA * Update hogaak_arisen_necropolis.txt --------- Co-authored-by: tool4ever <therealtoolkit@hotmail.com> * Allow selected cards in authored AI decks (Card-Forge#11684) Co-authored-by: Agetian <stavdev@mail.ru> * Teach AI the Embargo and Donate setup (Card-Forge#11688) Co-authored-by: Agetian <stavdev@mail.ru> * Improve AI handling of reveal-count effects (Card-Forge#11712) Co-authored-by: tool4EvEr <tool4EvEr@> * Fix self-sacrificing mana ritual source count (Card-Forge#11725) * Add Japanese translations for MKM and DSK (Card-Forge#11722) * Refactor render, fix dispose call, add OverlayText (Card-Forge#11730) * Refactor render, fix dispose call, add OverlayText * move screenshot, adventure and classic render on their own class * update OverlayText, FrameRate, limit Spritebatch capacity * null check * unused import * quick fix rendering of OverlayText on non GameScene * Improve PumpAi timing logic (Card-Forge#11739) Co-authored-by: tool4EvEr <tool4EvEr@> * Fix Greensleeves ability definition (Card-Forge#11741) * Fix PumpAi creature tap cost timing (Card-Forge#11742) * Count all lands for sacrifice preference (Card-Forge#11743) * Perfected Theory (FRA) (Card-Forge#11745) * Refactor RewardActor, remove holdtooltip and use CardZoom via ViewRewardScene (Card-Forge#11737) * Refactor RewardActor, remove holdtooltip and use CardZoom via ViewRewardScene * remove unnecesary changes * rename batch, add comment * return generated image for cardpacks if cached image is not found * use RewardActor object reference for CardView image * clear CardView Object, update Zoom renders * refactor Graphics, cached CardView with objects to clear, limit graphics spritebatch capacity * New Game menu bugfix: Correct label alignment and fix text/style setters to properly invalidate the layout on MarqueeButton. (Card-Forge#11706) * quick fix on dispose * Added MSH Jumpstart (Card-Forge#11668) * Update printsheets.txt Added MSH Jumpstart packs. * Update blocks.txt Added MSH Jumpstart * Update config.json Added MSH Jumpstart * Mark Sifa Grent +1 as a planeswalker ability (Card-Forge#11748) * Edition updates: CMB1, FRA, SLD * Move prepare card text details to CardDetailUtil (Card-Forge#11635) * Rename batch and update Framerate Sprite count (Card-Forge#11749) * Rename batch and update framerate sprites count for GameStage and UIScene * update FrameRate * Remove alara pack shop which suddenly broke, preventing this plot-critical map from loading * Additional updates to reflect edition change from CON to CFX * Solitary Cell (FRA) (Card-Forge#11757) * Update Console-and-cheats.md (Card-Forge#11744) Remove inaccurate part of `clearnosell`'s description. * Realm of legends 1.073: Fallen Castles Rebalance (Card-Forge#11762) * Rebalance to white and red fallen castles * Full fallen castle rebalance * Another revision to fallen castle rebalance * Typo fix * update disposables * Make sim mode run without a display (Card-Forge#11761) `sim` is documented as the way to run AI matches on headless servers, but it has been unable to start without a display since 48f3ae1 (2022-04-16), and it failed with no output at all. Two defects combined. GuiDesktop resolved the screen scale from a static initializer, so merely loading the class called GraphicsEnvironment.getDefaultScreenDevice() and threw HeadlessException. Main installs the GUI interface before it parses argv, so sim died before it could read its own arguments. The screen scale is now resolved on first use, via a holder so the read stays lock-free on the paint path, and falls back to 1.0 when there is no display. Main sets java.awt.headless for the console modes before any AWT class loads -- unless the user set it explicitly -- so a desktop run of sim exercises the same path a server does. The crash was also invisible. Sentry's uncaught handler chains to whatever default handler is already installed, and nothing installed one this early, so the exception was reported and discarded without reaching stderr. Main now installs a printing handler before Sentry.init. It cannot simply be registerErrorHandling() moved up: that reads ForgeConstants.LOG_FILE, whose class initializer resolves ASSETS_DIR through GuiBase.getInterface(), so it needs the GUI interface already set -- and the window needing coverage includes setting it. Dialog entry points now degrade to a return value instead of throwing HeadlessException. This matters most for BugReportDialog: a crash mid-run built a dialog that threw, and that secondary exception replaced the crash being reported, so a failed batch run lost the actual bug. showOptionDialog returns -1 ("dialog closed without choosing", what FOptionPane already returns) rather than the default option, because SOptionPane.showConfirmDialog reads index 0 as Yes -- returning the default would silently approve destructive prompts such as overwriting a saved game state. Verified on a host with no DISPLAY: a full game completes and exits 0, as do 2-player, 3-player, best-of-N, Commander, Planechase, and a 4-player bracket tournament. Under Xvfb the GUI is unchanged, and HiDPI still reports 2.0 with -Dsun.java2d.uiScale=2. HeadlessStartupTest guards the regression. It forks a JVM with -Djava.awt.headless=true, since GraphicsEnvironment caches headlessness on first use and CI runs the suite under Xvfb with a real DISPLAY, so an in-process check would exercise the headful path and prove nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Clean up (Card-Forge#11767) * Cast Away Doubt (FRA) (Card-Forge#11768) * Sentry: skip obvious custom script error (Card-Forge#11769) * Reuse FrameBuffer * Edition updates: FRA * Update Premodern banlist: add Parallax Tide Parallax Tide was banned in Premodern effective January 2026, and this simple commit is long overdue! * Fix wrong update logic (Card-Forge#11774) * Fixed spelling mistake in printsheets.txt (Card-Forge#11775) * Move GifAnimation object to Assets, fix resource NPE (Card-Forge#11777) * Move GifAnimation object to Assets, fix resource NPE * reorder to prevent extra initialization * replace demo GIF preload * Generous Revival (FRA) (Card-Forge#11779) * Fixed typos in printsheets.txt * Architecture to skip GUI updates when simulating (Card-Forge#11780) * Implement Rulebreaker (+Partial implementation of DeckRule) (Card-Forge#11740) * Set threads to daemon to gracefully exit the game while disposing assets (Card-Forge#11765) * Set threads to daemon to gracefully exit the game while disposing assets * rename AdventureScreen to AdventureLauncher, fix freeze on awaitnextinput thread when exiting * resolve conflicts * revert NewGameMenu * revert this since it's not the scope of this PR * update dispose, revert shaperenderer initialization * Update Framebuffer generation (Card-Forge#11784) * Update Framebuffer generation * fix ondestroy bug * Use cheap blur, Add asset graphics for rendering * Crash Fix when restarting on Android (Card-Forge#11786) * Crash Fix when restarting on Android * dispose on destroy event --------- Co-authored-by: coder-5 <98986223+coder-5@users.noreply.github.com> Co-authored-by: Chris H <zenchristo@gmail.com> Co-authored-by: GitHub Actions <actions@github.com> Co-authored-by: Serafina <serafina2880@gmail.com> Co-authored-by: shoeless <shoeless@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: tool4EvEr <tool4EvEr@> Co-authored-by: tool4ever <therealtoolkit@hotmail.com> Co-authored-by: Fulgur14 <54345051+Fulgur14@users.noreply.github.com> Co-authored-by: Churrufli <churruflis@gmail.com> Co-authored-by: Paul Hammerton <paulhammerton1@hotmail.co.uk> Co-authored-by: Paul Hammerton <18243520+paulsnoops@users.noreply.github.com> Co-authored-by: BramTeurlings <bram.teurlings@live.nl> Co-authored-by: kevlahnota <anthonycalosa@gmail.com> Co-authored-by: MostCromulent <201167372+MostCromulent@users.noreply.github.com> Co-authored-by: Jetz72 <Jetz722@gmail.com> Co-authored-by: vihaan <vihaan.agrawalcoder@gmail.com> Co-authored-by: BigCrunch22 <59816726+BigCrunch22@users.noreply.github.com> Co-authored-by: Hans Mackowiak <hanmac@gmx.de> Co-authored-by: liamiak <liamiak@yahoo.com> Co-authored-by: Giovanni Menzano <giovanni.menzano@gmail.com> Co-authored-by: liamiak <liamiak1@gmail.com> Co-authored-by: Agetian <stavdev@mail.ru> Co-authored-by: voguelike <73729626+voguelike@users.noreply.github.com> Co-authored-by: Eradev <Eradev@users.noreply.github.com> Co-authored-by: Vanja <56617195+vanja-ivancevic@users.noreply.github.com> Co-authored-by: Saku3san <106969562+Saku3san@users.noreply.github.com> Co-authored-by: Zimmermann Gyula <graiondilach@hotmail.com> Co-authored-by: squee1968 <105706641+squee1968@users.noreply.github.com> Co-authored-by: Eradev <admin@eradev.com> Co-authored-by: monkyman64 <168941314+monkyman64@users.noreply.github.com> Co-authored-by: RogerSloan <1922907+RogerSloan@users.noreply.github.com> Co-authored-by: Good-Girls-Go-Out-At-Night <goodgirlsgooutatnight@gmail.com> Co-authored-by: Jamin Collins <jamin.collins@gmail.com> Co-authored-by: Valerio Maggio <1908453+leriomaggio@users.noreply.github.com> Co-authored-by: Valerio Maggio <leriomaggio@users.noreply.github.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.
No description provided.