Magic Duels tests and results

This topic should be used to post our tests and results with Magic Duels modding. I'm also going to share the contents of my test ZED with some cards, you can use them as a starting point if you want.
Test results for Amonkhet, the last expansion:
At the end of this post you can find a ZIP file with the contents of my test ZED, starting from Data_All_Platforms. You can make it a ZED with spirolone's "MDO_CreateZed" tool, or with my D15Tool's converter. In both cases, you'll also need the latest expansion's ZED data header, attached at the end of this post. Rename it to Data.bin if you use spirolone's tool, otherwise leave it named as it is.
Some warnings: please use a Steam emulator (look further below if you need it) or be really sure about what you are doing, I don't want any responsibility for what could happen to your real Steam profile.
Ignore the test card, it's useful to me in order to put abilities I need to test on it.
Here are some brief instructions on how to make a ZED file from my contents:
-------------
-------------
Test results for Amonkhet, the last expansion:
- Overriding cards is possible, but if the change is exterior, it won't be visibile in the collection nor in the deck builder: it's possible that those two places take the information from the big card pool files. Cards need to be compiled in order to be read.
- The expansion symbol on the cards is chosen according to the set_id attribute. While it's not possible for us to add new symbols because the textures' names are hard-coded in the executable, we can at least use the symbol we want among the existing ones. For example, set_id="DPM_SBX" will use the "D" symbol with the right rarity. With an unknown set_id, the symbol will always be the common "D".
- Since EMN, double-faced cards have an additional attribute in the TRANSFORMATION block which tells them the icon to use in the upper-left circle. Unfortunately, the values are hard-coded in the executable, so we can't use new ones. It would be possible to override either AFTERMATH_FRONT or AFTERMATH_BACK since they are identical, and use only the other one in aftermath cards, but we would need at least 2 in order to give proper symbols to new double-faced cards (like the Ixalan ones) so it wouldn't be very useful.
- The frames to use on double-faced cards aren't hard-coded... but there are flaws in how they are selected. For example, when the back face is a land, the frame is selected from the "_LAND_FRONT" ones. Example: Thaumatic Compass//Spires of Orazca: the back face will be loaded from C_LAND_FRONT.tdx, so it will have the "flippable" arrow indicator in the lower right. Still better than having a completely wrong frame anyway.
- We can implement a custom expansion filter in the collection menu. It won't work in the deck builder, but at least it allows to quickly reach custom cards in the collection without searching for them, and see if they look alright. Make a separate pool for your custom cards, with a unique content_id, id and plane_id, select a collection_logo_location (it must point to a .tdx file, without specifying the extension) and you're set. Here's what I did:
- My own collection filter | Open
- There might be a way to tweak the AI decks in solo mode without having to edit more than 5000 XML files. If you decompile Data_007\Data_All_Platforms\ExploreDecks\Ratings.lol you get a table like this:
- Ratings.lol excerpt | Open
By comparing difficulties and corresponding deck names, difficulty seems to be going the opposite direction: 3=supereasy, 2=easy, 1=medium, 0=hard. I'm not sure what "category" means (it doesn't seem to be 1:1 with the deck names) and I have no clue how "rating" is computed.
I fiddled with the file a bit, but all I could manage is to get the game frozen on start, then frozen on duel loading, then made the AI use an all-Forest deck (while the test deck I wrote should have had 20 Plains and 40 Anointer of Champions). - The official convoke doesn't work: when you could cast a spell by tapping creatures, it taps nothing.
- Starting with the Aether Revolt expansion, cards are in LOL format as well.
- Cards are loaded as Lua modules, and at the moment of the loading, those modules would be accessible (example: ABANDON_REASON_395028 is stored in content.cards.abandon_reason_395028). Unfortunately it seems that they aren't accessible during the duels (the content table is still accessible, but it only contains userdata at key 0).
- Cards whose file name starts with an underscore are no longer read by the game.
- Starting with the Kaladesh expansion, if you try to access Battle Mode while offline without having completed Gideon's campaign, the game will complain about the store not available and will just return to the main menu. There are 2 solutions for this problem, you can find the detailed steps on my test ZED contents section further below.
- Starting with the Kaladesh expansion, card pools are in LOL format (compiled Lua scripts). They can still be overwritten by plain Lua files (still with LOL extension) as we have always done for constants and functions. In this post you can find a full example of what you get by decompiling a LOL card pool, how it compares to the old XML format, and what you need to write in your own LOL file in order to make it work.
- For the Nyx frames they are using a full frame picture rather than adding only the Nyx border when needed... but they are still not associating Z_Nyx to the dual-color Nyx cards. So again, the Z_Nyx frame needs to be duplicated 10 times.
- Tejahn discovered that Planeswalkers' frames are linked to the Planeswalker's Multiverse ID. For example, any card using the same Multiverse ID as Jace Beleren (in Duels) will have Jace Beleren's frame. It seems there are no side effects for using the same Multiverse ID on different cards. Also, the Planeswalker should have the same number of abilities as the one from which the frame has been borrowed.
- It appears that the default Planeswalker frame (for when the game can't decide which one to use) is from Origins' Gideon:
- Ugin, the Spirit Dragon (with his own Multiverse ID) | Open
- Planeswalker frames must be generated with mip-maps (for a size of about 239 KB), otherwise the game will crash when trying to view them.
- Art ID for double-faced cards must use numbers. More about that here (at the end of the post).
With the Kaladesh expansion they started to use Art IDs with one letter at the end: the results may be different now. - The header for the custom ZED files should always be the one from the latest expansion in order to make the card pool substitutions with ease.
- Cards with multiple mana abilities don't work as intended: if used with manual tapping they are OK, but auto-tapping ends up tapping nothing. This also makes adding a basic land type work properly only on lands that already have one or more basic land types and no other mana ability.
- There's no forced_skip anymore for activated abilities. It's possible to use AUTO_SKIP always="1", but it won't work for players who disabled automatic resolution in the options. The most rule-compliant solution for approximating activated abilities that don't use the stack would be to enforce "split second" while they resolve.
- The game is unaware of activated abilities that use the AddMana function when auto-tapping. I'm sure it doesn't count them as mana abilities, either.
- The mana tokens are spawned into zone #10, which is ZONE_COMMAND_GENERAL, the same used for emblems.
- If a mana token is prevented from leaving the mana pool through a ZONE_CONSIDERED overriding trigger, you still see it, but it becomes unusable (I have yet to check if it's a visual bug and the mana token actually left the pool, or if the mana token is truly still there). Also, neither ZONECHANGE_BEGIN nor ZONECHANGE_END can catch the mana tokens leaving the mana pool (but they can catch them entering it).
- It's possible to spawn a mana token through MakeEmblem, but it won't count as available mana. This test, together with the previous one, makes me think that mana tokens are just an interface commodity, while the real mana pool is being handled internally in another way.
EDIT: I don't know how I could have missed it until now, but we actually have the mana pool as a new object type, with its own functions. Unfortunately, at the moment it supports just 2 functions: GetConvertedCost() which returns how much total mana you have in your mana pool, and Get(...) which returns how much mana of the specified color you have in your mana pool; the color is specified by using the SYMBOL constants (it still doesn't explain the purpose of the SYMBOL constants that don't represent a color). - The BECAME_TAPPED_FOR_MANA trigger is still broken.
- When activating a mana ability by manually tapping, the BECAME_TAPPED trigger fires before the mana token is created.
- By using SetZone(ZONE_ANYWHERE) and then refining the filter with multiple FE_ZONE, it seems possible to reach any number of zones at the same time when choosing a card, except for the zones that the choosing player is normally not allowed to see, for example the opponents' hands (and all libraries too, I'd guess, even if I haven't tested it).
- The function RemoveFromCombat() works as planned: cards like Gustcloak Savior and Lost in the Woods are now possible.
- Even though the new Emrakul isn't included, there have been experiments for controlling another player's turn... and in fact, there's a function to do that! When controlling another player's turn, a button appears in the lower-left corner of the screen: with that button you can toggle between your hand and your opponent's hand (the rest of the table doesn't flip so it might be a little counter-intuitive). I went this far in testing: if you want to make more tests, you can find Emrakul and Mindslaver in my test contents.
- Just as the Planeswalkers, the look of the energy reserve emblem is based on its Multiverse ID. Any emblem spawned with a different Multiverse ID will use the Planeswalkers' emblems layout (with card type, expansion icon and text box if there's any text to display).
- Spawning an emblem with no types makes it invisible, so hidden managers are still possible. I haven't checked if it reserves space for itself on the field or not.
- Spirolone discovered that the game already supports up to 8192 cards to be used in player decks, the problem is that it doesn't recognize the cards past ID #1023 as unlockable. They can be added manually to the decks by editing the profile; if you do that, then you can see them in the deck builder when you open the decks that contain them.
- If TurnFaceDown is used on a permanent on the battlefield, it doesn't visually look face down, but the IsFaceDown function returns true anyway. Maybe this could be useful for a new morph approximation?
- The MANA_PAID trigger seems unreliable about when it triggers and how many times it triggers: test it and you'll see what I mean. I have been able to see that it only carries a TriggerPlayer information.
- Poison counters work correctly, but are invisible. In case we want to use them, we need to introduce an emblem that keeps count of them (and, in case of need, can be used as manager).
- PLAYER_CHARACTERISTIC_DOESNT_DIE_ON_ZERO_LIFE is broken: you don't lose the game, but you can't cast spells while your life is 0 or lower. If you try, the game tells you that you don't have enough mana.
- A nonland card with no casting cost is still considered the same as having a casting cost of
and as such, it's castable (while it shouldn't).
- The HasCategory function could allow us to check for any ability.
- example | Open
- Support for hybrid mono-colored mana has been totally discontinued: if you write {2/U} as cost of a spell, it will count as
.
- It seems that support for Phyrexian mana has been discontinued as well: paying 2 life rather than the corresponding mana color seems impossible to do.
- About COST_MODIFICATION blocks (as seen in DotP2015 for Nemesis of Mortals): IncreaseCurrentCost is broken, while DecreaseCurrentCost works as planned. LinkedDC is unaccessible from within them.
- This is really strange: in any chest, register -1 doesn't seem to work properly.
- When a card loses its counters because of a zone change, no COUNTERS_CHANGED trigger is fired.
- FlipCoin makes the game crash. At least, coin flipping is something that's easily simulated by generating a random number between 0 and 1.
- RandomNumberBetween seems somehow rigged: two consecutive calls with arguments 0 and 1 always return two different results. I'd advise to use math.random instead.
- MTG():PlusOnePlusOneCounters() and MTG():GetCountersType("+1/+1") return the same number. I would guess it's the same for all P/T counters. I know it doesn't seem important, but it could be in the future.
- As in all previous games, characteristics outside of the official ones can't be set. Trying to set a characteristic with a negative index also makes the game crash.
- The BEGINNING_OF_DUEL trigger fires before mulligans, however there seem to be restrictions to what can be done with it: I have tested that tokens can't be created and life can't be gained. Queries can be issued, but if more than 1 card at the same time presents a query with this trigger, you won't be able to close the query window and thus progress with the game.
- The FINALISE_STACK_OBJECT trigger seems to be a sort of "spell or ability played" trigger: in other words, it fires as soon as anything hits the stack.
- If a card has an activated ability with active_zone="ZONE_HAND" (such as cycling), trying to cast that card normally will just zoom it rather than casting it. The bug can be circumvented by adding a UTILITY_ABILITY for casting the card for its normal cost.
- Changing the controller of an emblem is visually bugged: the emblem will still be shown on the previous controller's side, while eventual other cards controlled by that player will overlap it.
- Counter-intuitive facts about BEGINNING_OF_PLAYER_STEP trigger (and the non-player version too, I guess):
- In the untap step, it triggers after the permanents have been untapped.
- In the combat damage step, it triggers after the damage has been dealt.
At the end of this post you can find a ZIP file with the contents of my test ZED, starting from Data_All_Platforms. You can make it a ZED with spirolone's "MDO_CreateZed" tool, or with my D15Tool's converter. In both cases, you'll also need the latest expansion's ZED data header, attached at the end of this post. Rename it to Data.bin if you use spirolone's tool, otherwise leave it named as it is.
Some warnings: please use a Steam emulator (look further below if you need it) or be really sure about what you are doing, I don't want any responsibility for what could happen to your real Steam profile.
Ignore the test card, it's useful to me in order to put abilities I need to test on it.

Here are some brief instructions on how to make a ZED file from my contents:
- Download my D15Tool and the ZED header (from the attachment) then put both in the same folder.
- Start D15Tool. Ignore the "Workspace" tab, that's still only for DotP2015; use the "Converter" tab for all the conversions you need. Remember to select the correct bin file in the "Data file for ZED header" box.
- Create a folder wherever you want on your PC, call it Data_0xx where xx are the 2 digits you prefer (as long as they are higher than the current expansion's digits) and extract my test ZED contents into it. Verify that you extracted the whole folder structure: you should have Data_All_Platforms inside Data_0xx.
- Drag and drop the Data_0xx folder onto D15Tool's "Converter" tab, select the Magic Duels folder as destination, and you'll see Data_0xx.zed created. You could select another folder as destination and copy/move the newly created ZED to Magic Duels later, that's the same.
- Import an online profile where you completed Gideon's campaign. In the emulator section below you can find out how to do it.
- (Suggested by spirolone) You'll use a clean profile for this. That means you could potentially use the old trick to move all cards to the MO_SHOEBOX_PLAYER_POOL card pool and get them all unlocked when you unlock the starter box... if you have the patience to write them.
Anyway here are the steps:
- Before starting the game for the first time with the clean profile, rename DATA_005.ZED so that it doesn't get read by the game (e.g. _DATA_005.ZED).
- Start the game, go to Battle Mode (the game will complain that you should do the campaign first, go on anyway), unlock the starter box.
- Close the game and bring back DATA_005.ZED to its original name.
- Restart the game. Now you can play offline in Battle Mode again.
-------------
- Open here if you need the emulator | Open
-------------