Forge version 1.5.40
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins
48 posts
• Page 3 of 4 • 1, 2, 3, 4
Re: Forge version 1.5.40
by Agetian » 02 Jun 2015, 17:26
@ Krazy: Thanks! I think I got it right then! 
- Agetian

- Agetian
- Agetian
- Programmer
- Posts: 3489
- Joined: 14 Mar 2011, 05:58
- Has thanked: 684 times
- Been thanked: 572 times
Re: Forge version 1.5.40
by Agetian » 04 Jun 2015, 07:07
r29558: I improved the way the colored mana symbols in mana cost count is represented in deck editor statistics. Let me know if you have any issues with it.
- Agetian
- Agetian
- Agetian
- Programmer
- Posts: 3489
- Joined: 14 Mar 2011, 05:58
- Has thanked: 684 times
- Been thanked: 572 times
Re: Forge version 1.5.40
by Agetian » 05 Jun 2015, 15:22
A little bit of a brainstorm: I'm looking into the way to make the game consider each object returning from graveyard a new object. So far, the easiest and the most logical way of doing it that I've devised is to create a copy of the card and assign a new ID to it. That being said, so far we have deliberately interpreted the card ID as something intrinsic to it that doesn't ever change in the course of the game. However, the card ID is also something that identifies a card as a particular unique object, and distinguishing a new object compared to the old object by modifying its ID seems logical. I have a few questions:
1) Is it viable, in your opinion, to alter the card ID when it's recreated as a part of returning from graveyard (to the battlefield, in particular) in order to distinguish it as a new object?
2) If it is, do you know anything that this type of code (expressed simply as something like "Card copied = CardFactory.copyCard(c, true)") can potentially break?
3) If it's not a viable solution to the issue, do you have any other ideas as to how this might be implemented in a better way?
P.S. A simple Sun Titan + Animate Dead + Angelic Renewal test indicates that altering the card's ID to indicate that it's now a new object definitely works. That being said, I haven't tested anything else yet.
P.P.S. I'm running some tests now but if this is ever committed, then it'll be committed post-1.5.40 because of a big chance of potential break-ups.
- Agetian
1) Is it viable, in your opinion, to alter the card ID when it's recreated as a part of returning from graveyard (to the battlefield, in particular) in order to distinguish it as a new object?
2) If it is, do you know anything that this type of code (expressed simply as something like "Card copied = CardFactory.copyCard(c, true)") can potentially break?
3) If it's not a viable solution to the issue, do you have any other ideas as to how this might be implemented in a better way?
P.S. A simple Sun Titan + Animate Dead + Angelic Renewal test indicates that altering the card's ID to indicate that it's now a new object definitely works. That being said, I haven't tested anything else yet.
P.P.S. I'm running some tests now but if this is ever committed, then it'll be committed post-1.5.40 because of a big chance of potential break-ups.
- Agetian
- Agetian
- Programmer
- Posts: 3489
- Joined: 14 Mar 2011, 05:58
- Has thanked: 684 times
- Been thanked: 572 times
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Forge version 1.5.40
by Chris H. » 05 Jun 2015, 16:27
friarsol wrote:Is there a release coming today?
I have a little free time today and this weekend. I am now tryig to figure out the mods that need to be made to the settings.xml file.
-
Chris H. - Forge Moderator
- Posts: 6320
- Joined: 04 Nov 2008, 12:11
- Location: Mac OS X Yosemite
- Has thanked: 644 times
- Been thanked: 643 times
Re: Forge version 1.5.40
by KrazyTheFox » 05 Jun 2015, 17:12
If you do a release before I get home, could you add these to the changes.txt file for me? I forgot to do so last night.
Three new quest preferences (Playset Size: Basic Lands, Playset Size: Any Number, and Playset Size) have been added to control the number of cards to keep before selling extras in quest mode. One is for basic lands, one is for "unlimited" cards (Relentless Rats and Shadowborn Apostle), and the last one is for all other cards. This is mostly useful when playing for antes and you want to keep an extra couple of cards on hand, just in case, or if you want to keep fewer copies of basic lands around.
Card images for the latest sets are now available for download, including Tempest Remastered and Modern Masters 2015. All images have also been moved to a new server for increased reliability and performance and many previously missing images have been added. There are still a few images missing in Forge and rectifying that is an ongoing effort.
-
KrazyTheFox - Programmer
- Posts: 725
- Joined: 18 Mar 2014, 23:51
- Has thanked: 66 times
- Been thanked: 226 times
- Agetian
- Programmer
- Posts: 3489
- Joined: 14 Mar 2011, 05:58
- Has thanked: 684 times
- Been thanked: 572 times
Re: Forge version 1.5.40
by Marek14 » 05 Jun 2015, 19:29
I would say that ideally there should be two kinds of ID -- physical ID that is tied to the card as such and internal ID that can be invisible to players and that simply identifies an unique object. That could simply be a 4-byte integer incremented by one whenever a new object is created.Agetian wrote:A little bit of a brainstorm: I'm looking into the way to make the game consider each object returning from graveyard a new object. So far, the easiest and the most logical way of doing it that I've devised is to create a copy of the card and assign a new ID to it. That being said, so far we have deliberately interpreted the card ID as something intrinsic to it that doesn't ever change in the course of the game. However, the card ID is also something that identifies a card as a particular unique object, and distinguishing a new object compared to the old object by modifying its ID seems logical. I have a few questions:
1) Is it viable, in your opinion, to alter the card ID when it's recreated as a part of returning from graveyard (to the battlefield, in particular) in order to distinguish it as a new object?
2) If it is, do you know anything that this type of code (expressed simply as something like "Card copied = CardFactory.copyCard(c, true)") can potentially break?
3) If it's not a viable solution to the issue, do you have any other ideas as to how this might be implemented in a better way?
P.S. A simple Sun Titan + Animate Dead + Angelic Renewal test indicates that altering the card's ID to indicate that it's now a new object definitely works. That being said, I haven't tested anything else yet.
P.P.S. I'm running some tests now but if this is ever committed, then it'll be committed post-1.5.40 because of a big chance of potential break-ups.
- Agetian
A card would be assigned a new internal ID whenever it changes a zone (plus in a corner case of being "re-exiled", as can happen, for example, when you cast Pull from Eternity on a card imprinted on Chrome Mox and the card is put into exile instead of graveyard thanks to Leyline of the Void).
For example: Fiend Hunter enters the battlefield and exiles a creature. Once it moves into exile, it gets new internal ID, and that ID is stored in Fiend Hunter. Then, when Fiend Hunter leaves the battlefield, it simply moves the card with stored internal ID (or all such cards if Strionic Resonator was used) to the battlefield, if such card exists. If a token is exiled, it will get an ID and it will be stored, but the game rules will delete the token afterwards, so the ID won't point at anything. If the exiled card is moved from exile by any means, its ID will be invalid. All will work well.
One important thing, though, is that each physical card should store its previous internal ID for things that care about zone changes.
Puppet Master is a classic example. It triggers on a creature dying, and although it technically triggers before the event, it could probably just store the internal ID of the card in graveyard. But to return ITSELF properly, it has to look for a card in a graveyard whose before-last internal ID corresponds to its own. It might not know its own graveyard ID when it triggers.
Re: Forge version 1.5.40
by friarsol » 05 Jun 2015, 19:33
It kinda sounds like these things just need to be checking the timestamps that are recorded versus the timestamp of the current object. If they are different then the two objects are different. This is what happens in the targeting code for fizzling.
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Forge version 1.5.40
by Agetian » 05 Jun 2015, 19:40
It's an interesting idea to check the timestamps. Are the timestamps recorded on spell abilities themselves (that are on stack)? (by the way, if you have some time and if you have an idea as to how to potentially work around it, would you like to try it?)
- Agetian
- Agetian
- Agetian
- Programmer
- Posts: 3489
- Joined: 14 Mar 2011, 05:58
- Has thanked: 684 times
- Been thanked: 572 times
Re: Forge version 1.5.40
by friarsol » 05 Jun 2015, 22:02
I think the issue is that when AbilityUtils.getDefinedCards() is pulling the cards that are remembered it doesn't take them as they are remembered, it's taking their current state.Agetian wrote:It's an interesting idea to check the timestamps. Are the timestamps recorded on spell abilities themselves (that are on stack)? (by the way, if you have some time and if you have an idea as to how to potentially work around it, would you like to try it?)
- Agetian
Notice the difference between Remembered and DirectRemembered. In many of these circumstances, we probably want to be using the DirectRemembered aspect instead of the Remembered aspect.
I ran a similar test: Rendclaw Trow and Animate Dead (with a way to put the Trow in the graveyard - Puncture Blast, and a way to kill the Trow after its animated - Shock).
In fact, I just tried to change AnimateDead from Remembered to DirectRemembered and it resolved this issue.
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Forge version 1.5.40
by Agetian » 06 Jun 2015, 03:58
Thanks so much for looking into it, Sol! This is an interesting find indeed, thanks for pointing me towards DirectRemembered! I'll dig through the code base a little bit more. I'm curious if that other issue that was mentioned recently (with the "aristocrats" combo not working for the same reason) can also be remedied in a similar fashion... (I admit I have a very vague idea as to how the combo is even supposed to work, so I can't even reproduce it yet
).
- Agetian

- Agetian
- Agetian
- Programmer
- Posts: 3489
- Joined: 14 Mar 2011, 05:58
- Has thanked: 684 times
- Been thanked: 572 times
Re: Forge version 1.5.40
by mastroego » 06 Jun 2015, 10:56
So, you cast Fiend Hunter.
1.
As it enters the battlefield, the trigger to exile target creature goes on the stack.
2.
While the first trigger is still on the stack, you sacrifice the Hunter, which you can do with any card like Cartel Aristocrats.
3.
Since the Hunter gets sacrificed, he leaves the battlefield and its second ability fires. So this trigger also goes on the stack. Notice that the first trigger hasn't resolved yet! You're sacrificing the Hunter before it can.
4.
The second trigger resolves, and it should return the exiled card to the battlefield... except that, no card has been exiled yet! So no card is returned, and the possibility to return it is "wasted".
5.
The first trigger resolves, a creature is exiled, and now it has no hope to ever return. In theory.
6.
You reanimate (somehow) Fiend Hunter, and when he enters the battlefield again, you should be able to repeat the whole cycle with another target victim.
Except Forge mistakenly remembers the first one, and returns that, when you sacrifice the Hunter again.
I think that's the way I think it works.
Hope this helps
1.
As it enters the battlefield, the trigger to exile target creature goes on the stack.
2.
While the first trigger is still on the stack, you sacrifice the Hunter, which you can do with any card like Cartel Aristocrats.
3.
Since the Hunter gets sacrificed, he leaves the battlefield and its second ability fires. So this trigger also goes on the stack. Notice that the first trigger hasn't resolved yet! You're sacrificing the Hunter before it can.
4.
The second trigger resolves, and it should return the exiled card to the battlefield... except that, no card has been exiled yet! So no card is returned, and the possibility to return it is "wasted".
5.
The first trigger resolves, a creature is exiled, and now it has no hope to ever return. In theory.
6.
You reanimate (somehow) Fiend Hunter, and when he enters the battlefield again, you should be able to repeat the whole cycle with another target victim.
Except Forge mistakenly remembers the first one, and returns that, when you sacrifice the Hunter again.
I think that's the way I think it works.
Hope this helps

Re: Forge version 1.5.40
by Agetian » 06 Jun 2015, 15:18
I just tried these steps (with the reanimation taken care of via Animate Dead) and it worked correctly for me, I was able to exile the second creature without returning the first no problem... :/
- Agetian
- Agetian
- Agetian
- Programmer
- Posts: 3489
- Joined: 14 Mar 2011, 05:58
- Has thanked: 684 times
- Been thanked: 572 times
Re: Forge version 1.5.40
by mastroego » 06 Jun 2015, 15:22
cool, but indeed I think Animate Dead was just fixed by friarsol 
Maybe similar cards should be checked to see if they have the same problem. Also Xyx may have been using some other tricks to revive the creature instead of Animate Dead

Maybe similar cards should be checked to see if they have the same problem. Also Xyx may have been using some other tricks to revive the creature instead of Animate Dead

48 posts
• Page 3 of 4 • 1, 2, 3, 4
Who is online
Users browsing this forum: No registered users and 36 guests