It is currently 22 Aug 2025, 13:11
   
Text Size

Bug Reports (snapshot builds)

Post MTG Forge Related Programming Questions Here

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

Re: Bug Reports (snapshot builds)

Postby Fallen » 22 Nov 2012, 08:17

Thanks, going to test with forge-1.3.2-20121121.123153-5 to see if it still persists.
Fallen
 
Posts: 17
Joined: 24 Feb 2010, 16:28
Has thanked: 0 time
Been thanked: 1 time

Re: Bug Reports (snapshot builds)

Postby RumbleBBU » 22 Nov 2012, 11:36

My neverending quest for the fix to the challenge ConcurrentModificationException continues.

So far I've isolated where it happens...now I just cannot figure out the how/why part.

When you have preset cards in a quest challenge, setupPlayZone (in GuiDisplayUtil.java) calls the CardPanelContainer method addCard() to add it. This method adds the card to the relevant panels and then calls the doLayout() method. Since we are now talking about a PlayArea, which extends the CardPanelContainer class, we need to look at the doLayout() method in that class.

The doLayout() method does some stuff and then calls its private positionAllCards() method to position the preset cards in their proper places. The main part of this method is a loop ("for (final CardStackRow row : this.rows) {") that goes through the rows. And inside this loop things go haywire. Here's the whole method:

| Open
Code: Select all
    private void positionAllCards()
    {
        // Position all card panels.
        int x = 0;
        int y = PlayArea.GUTTER_Y;
       
        for (final CardStackRow row : this.rows) {
            int rowBottom = 0;
            x = PlayArea.GUTTER_X;
            for (int stackIndex = 0, stackCount = row.size(); stackIndex < stackCount; stackIndex++) {
                final CardStack stack = row.get(stackIndex);
                // Align others to the right.
                if (RowType.other.isType(stack.get(0).getGameCard())) {
                    x = (this.playAreaWidth - PlayArea.GUTTER_X) + this.extraCardSpacingX;
                    for (int i = stackIndex, n = row.size(); i < n; i++) {
                        x -= row.get(i).getWidth();
                    }
                }
                for (int panelIndex = 0, panelCount = stack.size(); panelIndex < panelCount; panelIndex++) {
                    final CardPanel panel = stack.get(panelIndex);
                    final int stackPosition = panelCount - panelIndex - 1;
                    this.setComponentZOrder(panel, panelIndex);
                    final int panelX = x + (stackPosition * this.stackSpacingX);
                    final int panelY = y + (stackPosition * this.stackSpacingY);
                    panel.setCardBounds(panelX, panelY, this.cardWidth, this.cardHeight);
                }
                rowBottom = Math.max(rowBottom, y + stack.getHeight());
                x += stack.getWidth();
            }
            y = rowBottom;
        }
    }
Now what happens is this: while the for loop is running, doLayout() gets called again and, consequently, positionAllCards() gets called again, too. Both exit successfully.
But back in our 'main' loop, we notice, a-ha, somebody else (ie., the other doLayout()/positionAllCards() call) has modified our stuff while we were working on it -> ConcurrentModificationException!

To my understanding, there are two reasons why this could be happening:

1) A method used within the loop causes the doLayout() to trigger again. I was kind of hoping this was the explanation but so far I haven't been able to figure out which one it could be.

2) There is actually some other thread running that is also accessing the PlayArea and, by chance, does it simultaneously. This would be quite a bit harder to isolate and prevent.... :(

Any ideas?
User avatar
RumbleBBU
 
Posts: 394
Joined: 18 Aug 2012, 04:24
Has thanked: 29 times
Been thanked: 66 times

Re: Bug Reports (snapshot builds)

Postby Hellfish » 22 Nov 2012, 12:22

Only thing I can think of is to put s breakpoint at the top of doLayout and note down the call stack fot each call until the exception happens.The last one in particular, to see where it comes from.

Do you have a questdata to share?Mine isn't advsnced enough to test this.
So now you're
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
User avatar
Hellfish
Programmer
 
Posts: 1297
Joined: 07 Jun 2009, 10:41
Location: South of the Pumphouse
Has thanked: 110 times
Been thanked: 169 times

Re: Bug Reports (snapshot builds)

Postby moomarc » 22 Nov 2012, 13:56

Not sure if it'll help you, Rumble, but I've noticed that when playing Vanguard with the two command zones as separate panels (instead of the default docked tabs), you seem to get the concurrent modification at doLayout quite regularly so should make testing easier. At the least it's a quick way to get the game to a point where you have two cards starting the game on the battlefield.
-Marc
User avatar
moomarc
Pixel Commander
 
Posts: 2091
Joined: 04 Jun 2010, 15:22
Location: Johannesburg, South Africa
Has thanked: 371 times
Been thanked: 372 times

Re: Bug Reports (snapshot builds)

Postby RumbleBBU » 22 Nov 2012, 16:06

I believe I can now say with reasonable confidence that it is indeed a genuine multithreading issue.

I tried putting positionAllCards() call in PlayArea.java within an invokeLater(), and it seems to work now. But I need to do some more testing with it before I dare commit anything...

(Addendum. Actually, that sort of works. It still gives you an exception but works anyway. I need to examine this a bit more.)
User avatar
RumbleBBU
 
Posts: 394
Joined: 18 Aug 2012, 04:24
Has thanked: 29 times
Been thanked: 66 times

Re: Bug Reports (snapshot builds)

Postby RumbleBBU » 22 Nov 2012, 17:06

I chose to commit it anyway. It may still give you an exception message but the challenge works anyway, so it's at least better than the previous version (which made challenges unplayable).
User avatar
RumbleBBU
 
Posts: 394
Joined: 18 Aug 2012, 04:24
Has thanked: 29 times
Been thanked: 66 times

Re: Bug Reports (snapshot builds)

Postby Sloth » 22 Nov 2012, 18:04

RumbleBBU wrote:I chose to commit it anyway. It may still give you an exception message but the challenge works anyway, so it's at least better than the previous version (which made challenges unplayable).
When i look at the code i think this should be fixed in a bigger scope:
doLayout is only called by addCard, which is only called by setupPlayZone. I'm sure it would be much better for setupPlayZone to add all cards and then call doLayout only once (and not after each card).

I would like to fix this, but i've never experienced this error. If you tell me how to reproduce this (i.e. what card need to be in a challenge), i will give it a try.
User avatar
Sloth
Programmer
 
Posts: 3498
Joined: 23 Jun 2009, 19:40
Has thanked: 125 times
Been thanked: 507 times

Re: Bug Reports (snapshot builds)

Postby friarsol » 22 Nov 2012, 18:08

It looks like I'm getting this a bunch after the recent comodification change. Mostly when I kill something with a spell. This one triggered after I cast Assassinate on a tapped creature.

Crash | Open
Detailed error trace:
java.lang.IllegalArgumentException: component and container should be in the same top-level window
at java.awt.Container.checkAdding(Unknown Source)
at java.awt.Container.setComponentZOrder(Unknown Source)
at forge.view.arcane.PlayArea.positionAllCards(PlayArea.java:277)
at forge.view.arcane.PlayArea.access$7(PlayArea.java:256)
at forge.view.arcane.PlayArea$1.run(PlayArea.java:251)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
Last edited by friarsol on 22 Nov 2012, 18:21, edited 1 time in total.
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 Sloth » 22 Nov 2012, 18:13

Ok, i was able to reproduce this error. I will restructure it like i said.

EDIT: Commited. Has it worked? Any side effects?
User avatar
Sloth
Programmer
 
Posts: 3498
Joined: 23 Jun 2009, 19:40
Has thanked: 125 times
Been thanked: 507 times

Re: Bug Reports (snapshot builds)

Postby moomarc » 23 Nov 2012, 07:18

Sloth wrote:Ok, i was able to reproduce this error. I will restructure it like i said.

EDIT: Commited. Has it worked? Any side effects?
Seems to have fixed the Leylines in Constructed mode at the very least. There's still a comodification crash when stargting a Vanguard match with the Command zone visible, so someone with an advanced quest needs to test the Challenges and pets.
Crash | Open
null


Version:
Forge version SVN

OS: Windows 7 Version: 6.1 Architecture: x86

Java Version: 1.6.0_35 Vendor: Sun Microsystems Inc.

Detailed error trace:
java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
at java.util.AbstractList$Itr.next(Unknown Source)
at forge.view.arcane.PlayArea.positionAllCards(PlayArea.java:264)
at forge.view.arcane.PlayArea.doLayout(PlayArea.java:255)
at forge.gui.GuiDisplayUtil.setupPlayZone(GuiDisplayUtil.java:282)
at forge.gui.match.nonsingleton.CCommand$3.update(CCommand.java:59)
at java.util.Observable.notifyObservers(Unknown Source)
at java.util.Observable.notifyObservers(Unknown Source)
at forge.util.MyObservable.updateObservers(MyObservable.java:38)
at forge.game.GameNew.newGame(GameNew.java:154)
at forge.game.MatchController.startRound(MatchController.java:126)
at forge.gui.home.variant.CSubmenuVanguard$6.doInBackground(CSubmenuVanguard.java:153)
at javax.swing.SwingWorker$1.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at javax.swing.SwingWorker.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
-Marc
User avatar
moomarc
Pixel Commander
 
Posts: 2091
Joined: 04 Jun 2010, 15:22
Location: Johannesburg, South Africa
Has thanked: 371 times
Been thanked: 372 times

Re: Bug Reports (snapshot builds)

Postby RumbleBBU » 23 Nov 2012, 07:22

Sloth wrote:Ok, i was able to reproduce this error. I will restructure it like i said.

EDIT: Commited. Has it worked? Any side effects?
...doesn't seem to fix the problem with challenges. I'm getting (almost) the same CME as before in challenges that use preset cards. And the challenge is unplayable after that. :(

.
| Open
Code: Select all
java.util.ConcurrentModificationException
   at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
   at java.util.AbstractList$Itr.next(Unknown Source)
   at forge.view.arcane.PlayArea.positionAllCards(PlayArea.java:264)
   at forge.view.arcane.PlayArea.doLayout(PlayArea.java:255)
   at forge.gui.GuiDisplayUtil.setupPlayZone(GuiDisplayUtil.java:282)
   at forge.gui.match.nonsingleton.CField$17.update(CField.java:148)
   at java.util.Observable.notifyObservers(Unknown Source)
   at java.util.Observable.notifyObservers(Unknown Source)
   at forge.util.MyObservable.updateObservers(MyObservable.java:38)
   at forge.game.GameNew.newGame(GameNew.java:140)
   at forge.game.MatchController.startRound(MatchController.java:126)
   at forge.gui.home.quest.SSubmenuQuestUtil$2.doInBackground(SSubmenuQuestUtil.java:329)
   at javax.swing.SwingWorker$1.call(Unknown Source)
   at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
   at java.util.concurrent.FutureTask.run(Unknown Source)
   at javax.swing.SwingWorker.run(Unknown Source)
   at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
   at java.lang.Thread.run(Unknown Source)
(Note that even I don't get this always...just something like 90% of time. Since it is a multithreaded concurrency issue, a lot depends on sheer luck - whether the two threads happen to access the relevant objects simultaneously or not. And that can vary on different computers/platforms.)
User avatar
RumbleBBU
 
Posts: 394
Joined: 18 Aug 2012, 04:24
Has thanked: 29 times
Been thanked: 66 times

Re: Bug Reports (snapshot builds)

Postby Sloth » 23 Nov 2012, 16:08

Mmh, it looks like there are multiple threats calling setupPlayZone. Tracking the calls back leads to startGame which calls startRound in a doInBackground of a swingworker.

I moved most of this stuff outside of the worker and i think the error is gone. Please check.
User avatar
Sloth
Programmer
 
Posts: 3498
Joined: 23 Jun 2009, 19:40
Has thanked: 125 times
Been thanked: 507 times

Re: Bug Reports (snapshot builds)

Postby RumbleBBU » 23 Nov 2012, 18:55

Sloth wrote:Mmh, it looks like there are multiple threats calling setupPlayZone. Tracking the calls back leads to startGame which calls startRound in a doInBackground of a swingworker.

I moved most of this stuff outside of the worker and i think the error is gone. Please check.
I've launched a couple of challenges now...no CMEs so far. Looking good!

You, sir, are really living up to your signature! =D>
User avatar
RumbleBBU
 
Posts: 394
Joined: 18 Aug 2012, 04:24
Has thanked: 29 times
Been thanked: 66 times

Re: Bug Reports (snapshot builds)

Postby swordshine » 25 Nov 2012, 03:50

Equal Treatment needs "SpellDescription$ If any source would deal 1 or more damage to a creature or player this turn, it deals 2 damage to that creature or player instead. Draw a card."

When I use shotcut "E" to skip turns, some static abilities such as "creatures must attack if able" have no effect.
swordshine
 
Posts: 682
Joined: 11 Jul 2010, 02:37
Has thanked: 116 times
Been thanked: 87 times

Re: Bug Reports (snapshot builds)

Postby Agetian » 25 Nov 2012, 14:12

I have come across an uncommon, difficult to reproduce, unusual bug which was uncovered through posting events for the sound system: with the recent addition of the "Blocker Assigned" sound, there's a situation that happens under seemingly different circumstances in (very?) rare cases: sometimes, the "blocker assigned" sound will start to play at every phase switch. I double checked the code and the only time the Blocker Assigned event is posted is in the "addBlocker" routine, so for whatever reason, "addBlocker" is being sometimes called at every phase switch, but I have no idea by what or from where... There was no visible indication on the playfield that any blocker was added to anything (moreover, the addBlocker was fired outside of combat). Also, I have no idea how to best approach looking for this bug. If anyone has any idea what may cause this behavior or what a good strategy for solving it may be, please let me know.

P.S. The only clue that I have was that the last time I saw it, it started to happen after I played Captivating Glance on the opponent's creature (don't remember which one). However, a simple test case in an attempt to reproduce it happening did not cause the bug, I played Captivating Glance succesfully and played for quite a while afterwards and the buggy behavior wasn't triggered.

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

PreviousNext

Return to Developer's Corner

Who is online

Users browsing this forum: No registered users and 36 guests

Main Menu

User Menu

Our Partners


Who is online

In total there are 36 users online :: 0 registered, 0 hidden and 36 guests (based on users active over the past 10 minutes)
Most users ever online was 7303 on 15 Jul 2025, 20:46

Users browsing this forum: No registered users and 36 guests

Login Form