It is currently 12 Nov 2025, 23:09
   
Text Size

Bug Reports (snapshot builds)

Post MTG Forge Related Programming Questions Here

Moderators: timmermac, Agetian, friarsol, Blacksmith, KrazyTheFox, CCGHQ Admins

Re: Bug Reports (snapshot builds)

Postby Myrd » 28 Dec 2015, 05:45

I'm not sure if someone else had looked at this before, but I tried to figure out why exiled face-down cards that should be visible to certain players (e.g. via Hideaways or effects like Bane Alley Broker's ability) don't actually get shown revealed to the players that should be able to see them (usually, to the human player).

I did a bit of debugging and it looks like what happens is for those cards, the CardView's getCurrentState() corresponds to the Card's CardStateName.FaceDown state.

In such a case, the card's getAlternateState() actually has the normal state.

So, one way to fix this is to make any UIs that show cards (e.g. CardDetailPanel) have logic to this extent. For example, in CardDetailPanel.setCard(), the following logic can be added:

Code: Select all
        if (card != null && card.isFaceDown() && mayView)
            isInAltState = true;

        final CardStateView state = card == null ? null : card.getState(isInAltState);
I've tested the above and it mostly works. There's some hiccups - for example, the card rules text comes via state.getAbilityText() - which is TrackableProperty.AbilityText. The issue is that value was computed with CARDNAME being blank, so this needs to be fixed for the description to show up correctly.

Additionally, probably the above logic I quoted should only happen for cards that are not in play. As for example face-down Morph creatures should still show their morph creature info in the details panel. Which kind of raises the question of where to show the info from the other face of the card. Perhaps instead it would be better to have a button or something to separately show the regular face of a card when it's face down?

Additionally, the above change only makes the detail panel work. But it doesn't e.g. show the card name in any CardArea view - e.g. when opening the exile zone panel. So if we wanted to go that route, we'd need similar logic changes to other places (e.g. in CardPanel). And this is all for the desktop UI. I've not looked at whether mobile UI also needs a similar treatment.

But the other issue I see is it seems there's only two CardState's available, which doesn't seem correct according to the rules. For example, transform cards can be in 3 states - face up, face down and transformed. So maybe the underlying data structure needs to be updated first? Otherwise my logic above (isInAltState = true;) probably does the wrong thing for cards that can transform?

Anyone have any thoughts here? Have thought about this before? What's the right thing to do to solve this?

EDIT: Looks like the above code snippet isn't right, because mayView is always true for cards in battlefield and exile, regardless if they're face up or not. Seems it's intended for viewing cards in libraries and hands when those are revealed, as opposed to viewing face-down cards in other zones. Not sure if it makes sense to change that logic - as it seems that if the logic is updated, face down hidden cards now display differently )(i.e. name is no longer ??? and no info like "H1" is shown).
Last edited by Myrd on 03 Jan 2016, 18:30, edited 3 times in total.
Myrd
 
Posts: 87
Joined: 24 Nov 2014, 05:58
Has thanked: 4 times
Been thanked: 32 times

Re: Bug Reports (snapshot builds)

Postby friarsol » 30 Dec 2015, 01:46

Starting a quest mode game (with ante) and two active pets crashes for me. This was working earlier today:

Image Crash | Open
Token t:plantwall_lvl1 not found in: ../forge-gui/res\lists\token-images.txt
Token t:petape_lvl1 not found in: ../forge-gui/res\lists\token-images.txt
Token t:plantwall_lvl1 not found in: ../forge-gui/res\lists\token-images.txt
Token t:petape_lvl1 not found in: ../forge-gui/res\lists\token-images.txt
EDT > java.lang.StringIndexOutOfBoundsException: String index out of range: 2
at java.lang.String.substring(String.java:1907)
at forge.ImageFetcher.fetchImage(ImageFetcher.java:31)
at forge.gui.CardPicturePanel.getImage(CardPicturePanel.java:94)
at forge.gui.CardPicturePanel.setImage(CardPicturePanel.java:75)
at forge.gui.CardPicturePanel.setCard(CardPicturePanel.java:68)
at forge.screens.match.controllers.CPicture.showCard(CPicture.java:75)
at forge.screens.match.controllers.CDetailPicture.update(CDetailPicture.java:93)
at forge.screens.match.controllers.CDetailPicture.showCard(CDetailPicture.java:48)
at forge.screens.match.CMatchUI$2.run(CMatchUI.java:335)
at forge.GuiDesktop.invokeInEdtNow(GuiDesktop.java:72)
at forge.FThreads.invokeInEdtNowOrLater(FThreads.java:30)
at forge.screens.match.CMatchUI.setCard(CMatchUI.java:333)
at forge.screens.match.CMatchUI.setCard(CMatchUI.java:329)
at forge.gui.GuiChoose$1$1.valueChanged(GuiChoose.java:172)
at javax.swing.JList.fireSelectionValueChanged(JList.java:1798)
at javax.swing.JList$ListSelectionHandler.valueChanged(JList.java:1812)
at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:184)
at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:164)
at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:211)
at javax.swing.DefaultListSelectionModel.changeSelection(DefaultListSelectionModel.java:405)
at javax.swing.DefaultListSelectionModel.changeSelection(DefaultListSelectionModel.java:415)
at javax.swing.DefaultListSelectionModel.setSelectionInterval(DefaultListSelectionModel.java:459)
at javax.swing.JList.setSelectedIndex(JList.java:2212)
at javax.swing.JList.setSelectedValue(JList.java:2362)
at forge.gui.ListChooser$3.run(ListChooser.java:176)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:154)
at java.awt.WaitDispatchSupport$2.run(WaitDispatchSupport.java:182)
at java.awt.WaitDispatchSupport$4.run(WaitDispatchSupport.java:221)
at java.security.AccessController.doPrivileged(Native Method)
at java.awt.WaitDispatchSupport.enter(WaitDispatchSupport.java:219)
at java.awt.Dialog.show(Dialog.java:1082)
at java.awt.Component.show(Component.java:1651)
at java.awt.Component.setVisible(Component.java:1603)
at java.awt.Window.setVisible(Window.java:1014)
at java.awt.Dialog.setVisible(Dialog.java:1005)
at forge.view.FDialog.setVisible(FDialog.java:201)
at forge.toolbox.FOptionPane.setVisible(FOptionPane.java:279)
at forge.gui.ListChooser.show(ListChooser.java:183)
at forge.gui.ListChooser.show(ListChooser.java:157)
at forge.gui.GuiChoose$1.call(GuiChoose.java:183)
at forge.gui.GuiChoose$1.call(GuiChoose.java:146)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:241)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)


Alright, looks like ImageFetcher was trying to fetch "fake" cards like what's displayed in the Ante dialog box (and other places as well). So I just fixed that up.
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: Bug Reports (snapshot builds)

Postby danfly » 30 Dec 2015, 20:01

Description: [watching a computer duel in a tournament]

IllegalArgumentException | Open
Code: Select all
Forge Version:    1.5.46-r-1
Operating System: Linux 4.2.5-1-ARCH amd64
Java Version:     1.8.0_66 Oracle Corporation

java.lang.IllegalArgumentException: AI confirmAction does not know what to decide about null mode (api is null).
   at forge.ai.AiController.confirmAction(AiController.java:947)
   at forge.ai.PlayerControllerAi.confirmAction(PlayerControllerAi.java:165)
   at forge.game.ability.effects.ChangeZoneEffect.changeZonePlayerInvariant(ChangeZoneEffect.java:740)
   at forge.game.ability.effects.ChangeZoneEffect.changeHiddenOriginResolve(ChangeZoneEffect.java:614)
   at forge.game.ability.effects.ChangeZoneEffect.resolve(ChangeZoneEffect.java:352)
   at forge.game.ability.AbilityApiBased.resolve(AbilityApiBased.java:60)
   at forge.game.ability.AbilityUtils.resolveApiAbility(AbilityUtils.java:1252)
   at forge.game.ability.AbilityUtils.resolve(AbilityUtils.java:1234)
   at forge.ai.ComputerUtil.playNoStack(ComputerUtil.java:269)
   at forge.ai.PlayerControllerAi.playSpellAbilityNoStack(PlayerControllerAi.java:314)
   at forge.game.trigger.WrappedAbility.resolve(WrappedAbility.java:412)
   at forge.game.ability.AbilityUtils.resolveApiAbility(AbilityUtils.java:1252)
   at forge.game.ability.AbilityUtils.resolve(AbilityUtils.java:1234)
   at forge.game.zone.MagicStack.resolveStack(MagicStack.java:503)
   at forge.game.phase.PhaseHandler.startFirstTurn(PhaseHandler.java:979)
   at forge.game.GameAction.startGame(GameAction.java:1438)
   at forge.game.Match.startGame(Match.java:96)
   at forge.match.HostedMatch$2.run(HostedMatch.java:220)
   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
   at java.lang.Thread.run(Thread.java:745)
danfly
 
Posts: 7
Joined: 25 Sep 2014, 17:08
Has thanked: 1 time
Been thanked: 1 time

Re: Bug Reports (snapshot builds)

Postby fmartel » 31 Dec 2015, 01:02

hello all, I'm building a commander deck B,R,G. My commander is Prossh, Skyraider of Kher. among the spells I've included Mercy Killing and Slave of Bolas.
When trying to start the game, Forge tells me that those 2 cards are incompatible with my commander's color. I find it untrue, since I can cast them for an alternate (green for killing, and red for bolas) cost

is there a way, in the future that Forge can recognize the alternate cost in commander ?
While I wait for it to be developped ( ;p ) What can you offer for a replacement ?

Cheers !
fmartel
 
Posts: 281
Joined: 31 Dec 2013, 19:27
Location: Québec City
Has thanked: 8 times
Been thanked: 4 times

Re: Bug Reports (snapshot builds)

Postby friarsol » 31 Dec 2015, 02:30

fmartel wrote:hello all, I'm building a commander deck B,R,G. My commander is Prossh, Skyraider of Kher. among the spells I've included Mercy Killing and Slave of Bolas.
When trying to start the game, Forge tells me that those 2 cards are incompatible with my commander's color. I find it untrue, since I can cast them for an alternate (green for killing, and red for bolas) cost

is there a way, in the future that Forge can recognize the alternate cost in commander ?
While I wait for it to be developped ( ;p ) What can you offer for a replacement ?

Cheers !
From the official rules - http://www.mtgcommander.net/rules.php

"While hybrid mana symbols may be played with either colour mana, they contribute both colours to the card's colour identity. Therefore they may only be played with a Commander whose identity includes ALL of the hybrid symbols' colours."
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: Bug Reports (snapshot builds)

Postby fmartel » 31 Dec 2015, 03:31

Hooo !
Thanks...
now I need to find out how to replace them :(
fmartel
 
Posts: 281
Joined: 31 Dec 2013, 19:27
Location: Québec City
Has thanked: 8 times
Been thanked: 4 times

Re: Bug Reports (snapshot builds)

Postby Zirbert » 01 Jan 2016, 01:22

Playing version 1.5.48-SNAPSHOT-30488. Counterbalance isn't working correctly when I control it and reveal a split card to its trigger. Instead of countering the opponent's spell if it matches one half or the other (as per http://blogs.magicjudges.org/articles/2 ... lit-cards/), it's countering the opponent's spell if its CMC equals the sum of both halves of the split card. A quick search of the archives shows this has been the case for at least a few betas, but some posts indicate it has also worked correctly in other versions.
Zirbert
 
Posts: 512
Joined: 13 Oct 2010, 16:04
Has thanked: 104 times
Been thanked: 19 times

Re: Bug Reports (snapshot builds)

Postby Agetian » 01 Jan 2016, 07:13

Zirbert wrote:Playing version 1.5.48-SNAPSHOT-30488. Counterbalance isn't working correctly when I control it and reveal a split card to its trigger. Instead of countering the opponent's spell if it matches one half or the other (as per http://blogs.magicjudges.org/articles/2 ... lit-cards/), it's countering the opponent's spell if its CMC equals the sum of both halves of the split card. A quick search of the archives shows this has been the case for at least a few betas, but some posts indicate it has also worked correctly in other versions.
The problem here is that the mechanism used by Counterbalance (X:Count$TopOfLibraryCMC) only returns one CMC value, the sum of CMCs of both sides of the split card - see, for example, CardFactoryUtil.java:1207-1208. This basically means that any card using TopOfLibraryCMC will be broken when used with split cards (these cards include Interpret the Signs, Judge Unworthy, Putrid Cyclops, Riddle of Lightning, Stormchaser Chimera). I couldn't figure out how to best work around this (because the result is passed from CardFactoryUtil.java to Card.java:4872 as a single X value and the check is performed only once). Does anyone have an idea how this is best fixed?..

EDIT: Tried to implement a solution in r30563 - it appears to work fine but it's a little too much of a "workaround", in my opinion. It's based on encoding two CMC values (for either side, that is) in one large integer and then detecting and processing that where needed. This mechanism assumes that no card CMC will ever be larger than 10 million, and no CMC of a split card face will ever be larger than 1 thousand. Seems reasonable, lol. However, I feel that this is not optimal, there's probably a much better and cleaner solution to this, but I'm out of ideas... if anyone knows how to implement this better, feel free to revert my change and try a better idea. :)

EDIT 2: r30564 - looks like Counterbalance is actually more of an exception, because e.g. Interpret the Signs has to count the CMCs of both card faces together, so I implemented a separate counting mechanism for now (Count$TopOfLibraryEachFaceCMC) that is used for Counterbalance, while other cards still use Count$TopOfLibrary so other cards are not broken by this change.

- Agetian
Agetian
Programmer
 
Posts: 3490
Joined: 14 Mar 2011, 05:58
Has thanked: 684 times
Been thanked: 572 times

Re: Bug Reports (snapshot builds)

Postby Agetian » 01 Jan 2016, 09:47

r30564: I'm not sure if this was intentional, but it looks like right now the online image fetcher will kick in every time a card picture is not found in the folder named after Code2 (even if the folder named after the set Code exists), which causes an issue if I already have all my pictures in a folder named after Code (but not Code2). For example, I have my HQ pictures for the Lorwyn set under the "LRW" folder. Prior to the introduction of the online image fetcher, there was no problem with that. Now, however, the game does not detect those pictures and instead fetches the [lower quality] pictures from magiccards.info and saves them to the "LW" folder (Code2 of the Lorwyn set). Then it loads those lower quality pictures from the LW folder and continues to ignore the existence of the LRW folder... I don't know if any other sets are affected, this is the first one where I detected this type of behavior.

- Agetian
Agetian
Programmer
 
Posts: 3490
Joined: 14 Mar 2011, 05:58
Has thanked: 684 times
Been thanked: 572 times

Re: Bug Reports (snapshot builds)

Postby Zirbert » 01 Jan 2016, 15:44

Agetian wrote:
Zirbert wrote:Playing version 1.5.48-SNAPSHOT-30488. Counterbalance isn't working correctly when I control it and reveal a split card to its trigger. Instead of countering the opponent's spell if it matches one half or the other (as per http://blogs.magicjudges.org/articles/2 ... lit-cards/), it's countering the opponent's spell if its CMC equals the sum of both halves of the split card. A quick search of the archives shows this has been the case for at least a few betas, but some posts indicate it has also worked correctly in other versions.
The problem here is that the mechanism used by Counterbalance (X:Count$TopOfLibraryCMC) only returns one CMC value, the sum of CMCs of both sides of the split card - see, for example, CardFactoryUtil.java:1207-1208. This basically means that any card using TopOfLibraryCMC will be broken when used with split cards (these cards include Interpret the Signs, Judge Unworthy, Putrid Cyclops, Riddle of Lightning, Stormchaser Chimera). I couldn't figure out how to best work around this (because the result is passed from CardFactoryUtil.java to Card.java:4872 as a single X value and the check is performed only once). Does anyone have an idea how this is best fixed?..

EDIT: Tried to implement a solution in r30563 - it appears to work fine but it's a little too much of a "workaround", in my opinion. It's based on encoding two CMC values (for either side, that is) in one large integer and then detecting and processing that where needed. This mechanism assumes that no card CMC will ever be larger than 10 million, and no CMC of a split card face will ever be larger than 1 thousand. Seems reasonable, lol. However, I feel that this is not optimal, there's probably a much better and cleaner solution to this, but I'm out of ideas... if anyone knows how to implement this better, feel free to revert my change and try a better idea. :)

EDIT 2: r30564 - looks like Counterbalance is actually more of an exception, because e.g. Interpret the Signs has to count the CMCs of both card faces together, so I implemented a separate counting mechanism for now (Count$TopOfLibraryEachFaceCMC) that is used for Counterbalance, while other cards still use Count$TopOfLibrary so other cards are not broken by this change.

- Agetian
Thanks for giving this a shot! Split cards can be a rules headache, so I imagine coding for them would be a nightmare.

The difference between Counterbalance and Interpret the Signs is that split cards allow the controller to use either half when doing a comparison (as Counterbalance). However, when an ability like Interpret just looks at a card and takes a action based on a characteristic, it sees and acts on both. That can be a tough hair to, um, split.

The comprehensive rules cover this in sections 705 and 706. http://blogs.magicjudges.org/articles/2 ... lit-cards/ and http://magic.wizards.com/en/articles/ar ... 2006-04-28 cover the same ground more readably.
Zirbert
 
Posts: 512
Joined: 13 Oct 2010, 16:04
Has thanked: 104 times
Been thanked: 19 times

Re: Bug Reports (snapshot builds)

Postby fmartel » 01 Jan 2016, 16:59

Description: [attacking with 2x Legion Loyalist, 1x Goblin Guide, 1x Goblin Piledriver. Having in play a Shared Animosity. The Piledriver (10/2) gets blocked by Firefist Striker (2/1) on the FS Phase]

RuntimeException | Open
Code: Select all
Forge Version:    1.5.48-SNAPSHOT-r30548
Operating System: Windows 7 6.1 x64
Java Version:     1.8.0_45 Oracle Corporation

java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
   at forge.GuiDesktop.invokeInEdtAndWait(GuiDesktop.java:94)
   at forge.FThreads.invokeInEdtAndWait(FThreads.java:50)
   at forge.screens.match.CMatchUI.assignDamage(CMatchUI.java:817)
   at forge.player.PlayerControllerHuman.assignCombatDamage(PlayerControllerHuman.java:304)
   at forge.game.combat.Combat.assignAttackersDamage(Combat.java:624)
   at forge.game.combat.Combat.assignCombatDamage(Combat.java:669)
   at forge.game.phase.PhaseHandler.onPhaseBegin(PhaseHandler.java:294)
   at forge.game.phase.PhaseHandler.startFirstTurn(PhaseHandler.java:976)
   at forge.game.GameAction.startGame(GameAction.java:1473)
   at forge.game.Match.startGame(Match.java:96)
   at forge.match.HostedMatch$2.run(HostedMatch.java:220)
   at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
   at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.reflect.InvocationTargetException
   at java.awt.EventQueue.invokeAndWait(Unknown Source)
   at java.awt.EventQueue.invokeAndWait(Unknown Source)
   at javax.swing.SwingUtilities.invokeAndWait(Unknown Source)
   at forge.GuiDesktop.invokeInEdtAndWait(GuiDesktop.java:88)
   ... 13 more
Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: 2
   at java.lang.String.substring(Unknown Source)
   at forge.ImageFetcher.fetchImage(ImageFetcher.java:31)
   at forge.CachedCardImage.<init>(CachedCardImage.java:22)
   at forge.view.arcane.CardPanel$2.<init>(CardPanel.java:169)
   at forge.view.arcane.CardPanel.updateImage(CardPanel.java:169)
   at forge.view.arcane.CardPanel.setCard(CardPanel.java:556)
   at forge.view.arcane.CardPanel.<init>(CardPanel.java:105)
   at forge.screens.match.VAssignDamage.addPanelForDefender(VAssignDamage.java:257)
   at forge.screens.match.VAssignDamage.<init>(VAssignDamage.java:198)
   at forge.screens.match.CMatchUI$8.run(CMatchUI.java:820)
   at java.awt.event.InvocationEvent.dispatch(Unknown Source)
   at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
   at java.awt.EventQueue.access$500(Unknown Source)
   at java.awt.EventQueue$3.run(Unknown Source)
   at java.awt.EventQueue$3.run(Unknown Source)
   at java.security.AccessController.doPrivileged(Native Method)
   at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
   at java.awt.EventQueue.dispatchEvent(Unknown Source)
   at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
   at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
   at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
   at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
   at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
   at java.awt.EventDispatchThread.run(Unknown Source)
fmartel
 
Posts: 281
Joined: 31 Dec 2013, 19:27
Location: Québec City
Has thanked: 8 times
Been thanked: 4 times

Re: Bug Reports (snapshot builds)

Postby Myrd » 01 Jan 2016, 20:02

fmartel wrote:Description: [attacking with 2x Legion Loyalist, 1x Goblin Guide, 1x Goblin Piledriver. Having in play a Shared Animosity. The Piledriver (10/2) gets blocked by Firefist Striker (2/1) on the FS Phase]

RuntimeException | Open
Code: Select all
Forge Version:    1.5.48-SNAPSHOT-r30548
Operating System: Windows 7 6.1 x64
Java Version:     1.8.0_45 Oracle Corporation

java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
   at forge.GuiDesktop.invokeInEdtAndWait(GuiDesktop.java:94)
   at forge.FThreads.invokeInEdtAndWait(FThreads.java:50)
   at forge.screens.match.CMatchUI.assignDamage(CMatchUI.java:817)
   at forge.player.PlayerControllerHuman.assignCombatDamage(PlayerControllerHuman.java:304)
   at forge.game.combat.Combat.assignAttackersDamage(Combat.java:624)
   at forge.game.combat.Combat.assignCombatDamage(Combat.java:669)
   at forge.game.phase.PhaseHandler.onPhaseBegin(PhaseHandler.java:294)
   at forge.game.phase.PhaseHandler.startFirstTurn(PhaseHandler.java:976)
   at forge.game.GameAction.startGame(GameAction.java:1473)
   at forge.game.Match.startGame(Match.java:96)
   at forge.match.HostedMatch$2.run(HostedMatch.java:220)
   at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
   at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.reflect.InvocationTargetException
   at java.awt.EventQueue.invokeAndWait(Unknown Source)
   at java.awt.EventQueue.invokeAndWait(Unknown Source)
   at javax.swing.SwingUtilities.invokeAndWait(Unknown Source)
   at forge.GuiDesktop.invokeInEdtAndWait(GuiDesktop.java:88)
   ... 13 more
Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: 2
   at java.lang.String.substring(Unknown Source)
   at forge.ImageFetcher.fetchImage(ImageFetcher.java:31)
   at forge.CachedCardImage.<init>(CachedCardImage.java:22)
   at forge.view.arcane.CardPanel$2.<init>(CardPanel.java:169)
   at forge.view.arcane.CardPanel.updateImage(CardPanel.java:169)
   at forge.view.arcane.CardPanel.setCard(CardPanel.java:556)
   at forge.view.arcane.CardPanel.<init>(CardPanel.java:105)
   at forge.screens.match.VAssignDamage.addPanelForDefender(VAssignDamage.java:257)
   at forge.screens.match.VAssignDamage.<init>(VAssignDamage.java:198)
   at forge.screens.match.CMatchUI$8.run(CMatchUI.java:820)
   at java.awt.event.InvocationEvent.dispatch(Unknown Source)
   at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
   at java.awt.EventQueue.access$500(Unknown Source)
   at java.awt.EventQueue$3.run(Unknown Source)
   at java.awt.EventQueue$3.run(Unknown Source)
   at java.security.AccessController.doPrivileged(Native Method)
   at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
   at java.awt.EventQueue.dispatchEvent(Unknown Source)
   at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
   at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
   at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
   at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
   at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
   at java.awt.EventDispatchThread.run(Unknown Source)
I believe this one should already be fixed by r30549
Myrd
 
Posts: 87
Joined: 24 Nov 2014, 05:58
Has thanked: 4 times
Been thanked: 32 times

Re: Bug Reports (snapshot builds)

Postby Myrd » 02 Jan 2016, 01:02

Agetian wrote:r30564: I'm not sure if this was intentional, but it looks like right now the online image fetcher will kick in every time a card picture is not found in the folder named after Code2 (even if the folder named after the set Code exists), which causes an issue if I already have all my pictures in a folder named after Code (but not Code2). For example, I have my HQ pictures for the Lorwyn set under the "LRW" folder. Prior to the introduction of the online image fetcher, there was no problem with that. Now, however, the game does not detect those pictures and instead fetches the [lower quality] pictures from magiccards.info and saves them to the "LW" folder (Code2 of the Lorwyn set). Then it loads those lower quality pictures from the LW folder and continues to ignore the existence of the LRW folder... I don't know if any other sets are affected, this is the first one where I detected this type of behavior.

- Agetian
Fixed. It was accidental - the Code2 in the Lorwyn.txt file got changed to "LW" whereas it was previously "LRW". I changed it back now. You can delete the LW folder.
Myrd
 
Posts: 87
Joined: 24 Nov 2014, 05:58
Has thanked: 4 times
Been thanked: 32 times

Re: Bug Reports (snapshot builds)

Postby Marek14 » 02 Jan 2016, 10:20

Zirbert wrote:Thanks for giving this a shot! Split cards can be a rules headache, so I imagine coding for them would be a nightmare.

The difference between Counterbalance and Interpret the Signs is that split cards allow the controller to use either half when doing a comparison (as Counterbalance). However, when an ability like Interpret just looks at a card and takes a action based on a characteristic, it sees and acts on both. That can be a tough hair to, um, split.

The comprehensive rules cover this in sections 705 and 706. http://blogs.magicjudges.org/articles/2 ... lit-cards/ and http://magic.wizards.com/en/articles/ar ... 2006-04-28 cover the same ground more readably.
Let's have a look at the converted mana cost mess associated with split cards!

General rule is that when asking a yes/no question, you get two answers and they are combined with logical OR. If you ask for a value, you will generally get the sum of both values.

So, out of all cards that care for CMC and are capable of interacting with split cards (I only mention cards that can currently interact with splits; soulshift, for example, COULD interact with split cards if they printed a split card that would be Tribal Instant - Spirit on at least one side, but that is unlikely. Anything that checks for CMC of spells will only ever see one side of split card, or sum of both if a split card is cast fused. Anything that checks for CMC of permanents will never hit a split card, of course):

Sum of both CMCs: Ad Nauseam, Augury Adept, Baneful Omen, Blast of Genius, Cerebral Eruption, Dark Confidant, Dark Tutelage, Daxos of Meletis, Duskmantle Seer, Elite Arcanist, Erratic Explosion, Erratic Mutation, Explosive Revelation, Friendly Fire, Goblin Machinist, Heed the Mists, Hellhole Rats, Hide//Seek, Ignite Memories, Infernal Genesis, Interpret the Signs, Judge Unworthy, Kaboom!, Kindle the Carnage, Lammastide Weave, Living Lore, Mercurial Chemister, Mindshrieker, Naya Soulbeast, Pain Seer, Phyrexian Devourer, Planeswalker's Favor, Planeswalker's Fury, Planeswalker's Mirth, Planeswalker's Scorn, Putrid Cyclops, Pyromancy, Reviving Vapors, Riddle of Lightning, Sarkhan the Mad, Singe-Mind Ogre, Slumbering Tora (if there was an Arcane split card, which there is not), Spellbound Dragon, Stormchaser Chimera, Surge of Strength, Talon Gates, Undying Flames, Vengeful Rebirth, Volcanic Vision, Wand of Ith

Lowest CMC counts: Cascade mechanic, Beseech the Queen, Bring to Light, Epic Experiment, Inquisition of Kozilek, Isochron Scepter, Sunforger, Venarian Glimmer, Villainous Wealth

Highest CMC counts: Appetite for Brains, Heretic's Punishment, Master of Predicaments, Mistmeadow Skulk (in the corner case where he would need protection from a card itself, not a spell), Psychic Battle, Scythe Specter*, Timesifter, Transgress the Mind

*Scythe Specter is a weird case. The highest CMC is checked when determining whether the split card you discarded has the highest CMC, but what if BOTH CMC's satisfy that condition? Can you choose to lose the lower amount of life? I am not sure.
EDIT: Asked on MTGSalvation and it seems like the highest CMC is consistently used with Scythe Specter.

Each CMC counts, individually:
Clash mechanic (A player wins the clash if his card has higher CMC than opponent's card. If one player reveals a split card, there are 2 comparisons to make. In case that the normal card's CMC is between the two CMCs of the split card, there is an answer "yes" when checking for each player's win, and so they both win the clash! In case of two split cards being revealed, each player goes through four checks and one "yes" answer is enough to win the clash. So: when checking whether a player wins the clash, compare highest CMC of his card with lowest CMC of the opponent's card -- and don't forget to check for each player's win separately!)
Transmute mechanic (you can find a split card if one of its sides matches CMC of the transmuted card)
Blazing Shoal, Disrupting Shoal, Nourishing Shoal, Shining Shoal, Sickening Shoal (you set the value of X, then you can discard a split card if it has the correct color and at least one of its sides has CMC X -- no matter if that side has the correct color or not)
Counterbalance (the spell is countered if its CMC matches either side of the split card)
Disciple of Deceit (you can find a split card if one of its sides matches CMC of the discarded card, if you discard a split card, you can find a card with CMC matching either of the discarded card's sides, you can find a split card on split card discard if any one of the 4 comparisons matches)
Firemind's Foresight (a split card can be found if either side matches the CMC you're currently looking for)
Grozoth (a split card can be found if either side has CMC 9 -- I think there are no such split cards at the moment, though)
Hisoka, Minamo Sensei (when a split card is discarded, a spell is countered if it matches CMC of either half)
Infernal Kirin (a split card is discarded if either half matches CMC of the spell)
Kaho, Minamo Historian (a split card can be cast if either half matches X)
Knollspine Invocation (a split card can be discarded if either half matches previously set X)
Kozilek, the Great Distortion (first, X is chosen, than a split card can be discarded if either side matches X)
Night Dealings (a split card can be found if either side matches X)
Panoptic Mirror (a split card can be exiled if either side matches X)
Prototype Portal/Soul Foundry (split cards can't be normally exiled to these, but if it SOMEHOW happened, X could be set as cost of either side; of course, no token could be created in this case)
Thought Prison (if a split card is imprinted, spell that matches CMC of either half will trigger Thought Prison)
Void (if either side matches the chosen number, the split card is discarded)
Last edited by Marek14 on 02 Jan 2016, 17:06, edited 1 time in total.
Marek14
Tester
 
Posts: 2774
Joined: 07 Jun 2008, 07:54
Has thanked: 0 time
Been thanked: 303 times

Re: Bug Reports (snapshot builds)

Postby ndlarsen » 02 Jan 2016, 13:36

Description: Casting Far / Away (Only the black away part) on AI opponents only creature (Charmbreaker Devils) during a EDH game.

ConcurrentModificationException | Open
Code: Select all
Forge Version:    1.5.48-SNAPSHOT-r30549
Operating System: Windows 7 6.1 amd64
Java Version:     1.8.0_66 Oracle Corporation

java.util.ConcurrentModificationException
   at java.util.LinkedList$ListItr.checkForComodification(Unknown Source)
   at java.util.LinkedList$ListItr.next(Unknown Source)
   at forge.ai.ability.AnimateAi.becomeAnimated(AnimateAi.java:422)
   at forge.ai.ability.AnimateAi.canPlayAI(AnimateAi.java:84)
   at forge.ai.SpellAbilityAi.canPlayAIWithSubs(SpellAbilityAi.java:21)
   at forge.ai.AiController.canPlaySa(AiController.java:648)
   at forge.ai.AiController.canPlayAndPayFor(AiController.java:635)
   at forge.ai.AiController.chooseSpellAbilityToPlay(AiController.java:1287)
   at forge.ai.AiController.getSpellAbilityToPlay(AiController.java:1264)
   at forge.ai.AiController.chooseSpellAbilityToPlay(AiController.java:1203)
   at forge.ai.PlayerControllerAi.chooseSpellAbilityToPlay(PlayerControllerAi.java:397)
   at forge.game.phase.PhaseHandler.startFirstTurn(PhaseHandler.java:924)
   at forge.game.GameAction.startGame(GameAction.java:1473)
   at forge.game.Match.startGame(Match.java:96)
   at forge.match.HostedMatch$2.run(HostedMatch.java:220)
   at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
   at java.lang.Thread.run(Unknown Source)
ndlarsen
 
Posts: 23
Joined: 12 Sep 2013, 12:43
Has thanked: 4 times
Been thanked: 0 time

PreviousNext

Return to Developer's Corner

Who is online

Users browsing this forum: No registered users and 27 guests

Main Menu

User Menu

Our Partners


Who is online

In total there are 27 users online :: 0 registered, 0 hidden and 27 guests (based on users active over the past 10 minutes)
Most users ever online was 9824 on 10 Nov 2025, 04:33

Users browsing this forum: No registered users and 27 guests

Login Form