I realized that learning lua would take some time for me, so instead I've almost finished writing this in a language I understand Soon I'll have tons more flexibility in the kinds of models I can experiment with, and as a bonus it benefits my work as well! I am all kinds of excited.
...You re-wrote the entirety of char-rnn in a different language? Which one? And how??
I've improved the decoder's MSE2 file output, and also put it in my own git repo where you can download it. It can now handle planeswalker cards, and choice cards are formatted nicely and such things. I should point out; due to the imperfect nature of the NN's output, I can't expect to have perfectly-formatted cards 100% of the time when this script runs. I aim for 99.9% of cards to be good, so only a few need the odd manual tweak here or there.
@Talcos, what scripts and checkpoints are you using for card generation these days? I presume it's sample_hs_v3, but I'm not sure which checkpoint it is. I'd like to generate a few hundred cards and import them straight into MSE2
Oh, someone mentioned MSE2 only being for Windows... I think that's strictly true, but I believe the WINE emulator can get around that for us (not tried that though).
Wild Enlightermancer 1WW
Creature - Human Soldier (Rare)
First strike
Miracle W (You may cast this card for its miracle cost when you draw it if it's the first card you drew this turn.)
2/2
Can the 'whispering a keyword ability overwrites the keyword ability the network would have added' problem (e.g. dragon forced to have delve doesn't have flying) be avoided by a multipass approach? Let the network generate what it wishes, then start over using that output to prime it, adding the keyword you want in the right place, but then add the start of what it originally did next, after the added keyword.
So if the first pass produced "Mointainspalking Dragon|...|Flying\When ~ enters..." then prime it with "Mointainspalking Dragon|...|Delve\F" and hopefully it will continue with "lying..." (but what it does next will take both Delve and Flying into account).
@Talcos, what scripts and checkpoints are you using for card generation these days? I presume it's sample_hs_v3, but I'm not sure which checkpoint it is. I'd like to generate a few hundred cards and import them straight into MSE2
Right now it's sample_hs_v3.lua for sampling. At some point in the future I might come out with a more robust sampling script, but it does decently at the moment.
However, I'll warn you that it's a GPU checkpoint, not a CPU one, and I'm still having problems with the latest version of char-rnn when I try to convert it over to CPU format. I get an error due to a float/double conversion issue. When I train a new network it'll be with the latest version of char-rnn, and this won't be an issue.
Wild Enlightermancer 1WW
Creature - Human Soldier (Rare)
First strike
Miracle W (You may cast this card for its miracle cost when you draw it if it's the first card you drew this turn.)
2/2
Whats an enlightermancer?
The machine churns out more questions than it does answers.
It looks like enlightened/enlightenment (the network learned that word from cards like Temple of Enlightenment and Isao, Enlightened Bushi) with the ending -mancer added on. The network likes to give creatures names that indicate agency. If I run the network and prime it with "wild enlight" for the name of the card, creature cards get names like...
Nearly all of these creatures made by the network are white and a minority are blue, and they're almost all wizards, soldiers, and clerics. What's interesting is that if I take out "wild" so that the network is free to make "enlight" be an adjective or a noun, I get cards like
The colors are all over the place, as are the creature types.
As for what "Wild Enlightermancer" really means, I suspect its that the creature operates by producing wondrous ephinanies. Specifically, they know where an enemy is going to be standing five seconds from the present moment, which is why the creature has first strike. And because it's an enlightermancer, one who operates on sudden, miraculous revelations, the card has the miracle ability. There, a complete justification for the card from top to bottom.
Can the 'whispering a keyword ability overwrites the keyword ability the network would have added' problem (e.g. dragon forced to have delve doesn't have flying) be avoided by a multipass approach? Let the network generate what it wishes, then start over using that output to prime it, adding the keyword you want in the right place, but then add the start of what it originally did next, after the added keyword.
So if the first pass produced "Mointainspalking Dragon|...|Flying\When ~ enters..." then prime it with "Mointainspalking Dragon|...|Delve\F" and hopefully it will continue with "lying..." (but what it does next will take both Delve and Flying into account).
Absolutely. The only problem is that we'd need to reformulate how we do the generation script because things you prime upstream affect things that get generated downstream, sometimes in subtle ways.
For instance, say you have this card:
Angelic Angel 3WW
Creature - Angel (Uncommon)
Flying 1W: Prevent the next 1 damage that would be dealt to target creature or player this turn.
4/4
Say you want the angel to have first strike, and you don't want to overwrite anything, so you isolate what comes before (flying) and after (the activated ability). You insert first strike, and right now the card looks like this:
Because at this point the network doesn't know that the activated ability is going to be added back in, it's likely going to want to put in a new and different ability. Unless you do something to stop it, you'll end up with this card:
Angelic Angel 3WW
Creature - Angel (Uncommon)
Flying, first strike
Whenever Angelic Angel deals combat damage to a player, that player skips his or her next combat phase. 1W: Prevent the next 1 damage that would be dealt to target creature or player this turn.
4/4
So there are some challenges there with getting the logic just right so that we avoid cluttered cards. But yeah, it can be done. Very good suggestion.
EDIT: I feel like we're getting very close to our first draft. Just a few more things here and there and we should be set.
I've been toying with the idea of a formalized Magic syntax that more closely follows programming conventions. If our corpus was written in the form of state changes and zone changes, the underlying parallels between exile, dies, bounce, etc would become clear.
For example, lets take the pseudocommand "zone.Change(target; origin; destination)".
"Exile target creature" could be written in the form "zone.Change(creature; battlefield; exile)"
"Return target artifact or enchantment card from a graveyard to its owner's hand would be written as zone.Change(artifact, enchantment; graveyard; hand)
Suddenly, the NN gets explicit information about the parallels between effects, and can make better educated guesses about the creative leaps it tries.
The post talks about the parser his program uses to makes sense of card text, and it's very close to what I was envisioning.
Would this syntax help the NN understand the rules better? Would it lead to creative stifling instead? Open the door to curious new effects? Promote overfitting? I'd love to hear thoughts and arguments.
Can the 'whispering a keyword ability overwrites the keyword ability the network would have added' problem (e.g. dragon forced to have delve doesn't have flying) be avoided by a multipass approach?
I've been toying with the idea of a formalized Magic syntax that more closely follows programming conventions. If our corpus was written in the form of state changes and zone changes, the underlying parallels between exile, dies, bounce, etc would become clear.
For example, lets take the pseudocommand "zone.Change(target; origin; destination)".
"Exile target creature" could be written in the form "zone.Change(creature; battlefield; exile)"
"Return target artifact or enchantment card from a graveyard to its owner's hand would be written as zone.Change(artifact, enchantment; graveyard; hand)
Suddenly, the NN gets explicit information about the parallels between effects, and can make better educated guesses about the creative leaps it tries.
The post talks about the parser his program uses to makes sense of card text, and it's very close to what I was envisioning.
Would this syntax help the NN understand the rules better? Would it lead to creative stifling instead? Open the door to curious new effects? Promote overfitting? I'd love to hear thoughts and arguments.
Honestly, I think an object-oriented approach to generating cards would be immensely beneficial. By reducing the syntactic complexity of each phrase as far as possible (essentially replacing each game term with a symbol), you eliminate the possibility of garbled outputs.
The only real possible downside is that a network trained in this manner might be less flexible in creating novel abilities. However, I think that comes down to how granular the encoding is.
And vim to run the tokenisation scripts. There's no documentation, so ping me an email if you need help using it: ep294 (at) sussex (dot) ac (dot) uk
Salut! Everything you've said is very, very interesting to me. Which reminds me, I really want to read your MSc dissertation when you finish, haha.
And thank you for sharing! I have to run for now, but I'll need to take a look at that later.
---
So I added in some syntax checks and a few semantics checks to the set construction script to eliminate garbage cards. It's a temporary fix until I can come up with a more robust solution. It gets rid of many mangled language problems (not all), and semantic issues like "kicked" without "kicker", inappropriate uses of "X", etc. I also threw in some temporary rules to excise creatures like slivers since we're working with a set that does not have slivers at all, and stuff like getting rid of transform creatures since I only grab the front face of those cards (I'll fix that at some point in the future). Overall, 24% of cards were eliminated on average from each set (that's roughly how much garbage there is in every dump).
I didn't attempt to eliminate any superfluous restrictions/actions, like activation restrictions on triggered abilities, or unnecessary shuffling. I figured that if we could just do that on our own.
There's also some unavoidable problem cards that have pointless qualities like this one:
Salt Rock Horror 3BB
Creature - Horror (uncommon)
Whenever Salt Rock Horror deals combat damage to a player, put a +1/+1 counter on it.
Remove a +1/+1 counter from Salt Rock Horror: put a +1/+1 counter on Salt Rock Horror.
(3/3)
They're rare and next to impossible to eliminate automatically because they're syntatically perfect and their abilities are appropriate for their colors. Our AI doesn't actually know how Magic is actually played so it isn't going to understand that Salt Rock Horror's ability isn't tactically useful.
Sample cards from the latest run for your entertainment (three mythics and two uncommons):
someone, martyr of kaldra (Y) 4WG
legendary creature ~ human wizard
vigilance, haste
when @ enters the battlefield, @ deals 3 damage to target creature or player.
whenever a creature enters the battlefield under your control, you may draw a card.
(4/3)
someone, worldwaker (Y) 1UB
legendary creature ~ human artificer
whenever @ deals combat damage to a player, that player sacrifices a creature. that player loses 1 life.
dredge 3
(2/2)
someone, archery (Y) 6RG
legendary creature ~ human wizard T: destroy target artifact or enchantment.
delve
(1/1)
Minister of the Fire 2R
Creature - Human Shaman (Uncommon)
When Minister of the Fire enters the battlefield, it deals 2 damage to each creature without flying and each player.
2/2
#Everything must burn!
Angel's Glory 1G
Sorcery (Uncommon)
Search your library for a creature card with converted mana cost 2 or less and put it onto the battlefield. Then shuffle your library.
You can see the latest set here (and comment on anything if you'd like):
As I'm sure you can see, there are cards here and there that'd need work. And if a card seems to totally unworkable, we could pick another one from one ourselves from the card dumps, which you can find here:
And just like that, this project has become that much more awesome.
Guys, if GoblynQueene's project and Talcos's project play well together, the result could be worth some real cheddar. The ability to churn out countless cards that are not only valid but actually based on an understanding of the Comprehensive Rules... The implications are staggering.
A network that understands the game's rules will be able to parse the difference between a useful ability and a drawback, which means that it won't look at Juzám Djinn and decide that 2BB for a 5/5 with "at the beginning of your upkeep, draw a card" is equally valid as 2BB for a 5/5 with "at the beginning of your upkeep, @ deals 1 damage to you."
A network that understands the rules will be able to make the distinction between permanents, spells, and players, so we don't get any "destroy target player" effects or sorceries that give themselves +1/+1 counters.
Just imagine what Wizards could do with something like that. Running on a top-end supercomputer, they could input a set of parameters ("make a bunch of Vampires," "design a 263-card set with a heavy graveyard theme," etc.) and crank out hundreds of thousands of perfectly valid cards every single day - more than they'd ever have time to actually look at.
They could then have their internal playtesters run drafts of the network-generated sets just to see what crazy mechanics it came up with and note what players liked the most, then run with it in human-designed sets down the line.
battlefield mage (A) 1UU
creature ~ human wizard UU, T: you may put a creature card from your hand onto the battlefield. if you do, search your library for a creature card, reveal it, and put it into your hand. if you do, shuffle your library.
dredge 2
(2/2)
#I'll take "'I win' buttons" for $1,000, please, Alex.
cateran raider (O) 3U
creature ~ serpent
flying
when @ enters the battlefield, sacrifice it unless you discard an artifact card.
threshold ~ as long as seven or more cards are in your graveyard, @ gets +X/+X, where X is your life total.
when @ dies, put a 3/3 green ape creature token onto the battlefield.
(3/3)
Ok, so after some prodding, I discovered that MSE2 does in fact run perfectly fine on Ubuntu 14.04 with WINE 1.7. Here's what I did:
Installed Wine 1.7 following these instructions. Wine 1.6 doesn't fully work with MSE2, which is why we need Wine 1.7.
Downloaded MSE2 and the 'Recent Styles' mse-installer (both in my original mse post which I will spoiler-text below). Double-clicking and running these (in the correct order, obviously) should work just fine as long as Wine is installed properly.
At this point you can open MSE2 by searching for it in the start menu, but if your install went like mine did, there will be some fonts missing, so let's solve that.
You'll need Beleren Bold, Beleren Small Caps Bold and Relay Medium. The first two I found here and the last one here. Open them in Font Viewer, click 'Install'.
Last step; clear the cache so Wine can see the new fonts. In a terminal, do 'sudo fc-cache -fv'.
And bingo! Fully-working and capable MSE2 in Ubuntu (as far as I know).
Here's my old posts regarding the actual decode.py script usage, download location and such:
In this case, it'll create a file called 'mseCards.mse-set' because that's the output file name we gave it.
To open this, you obviously need Magic Set Editor 2. You'll also need the m15 templates which don't come as default (for some daft reason). Click that link after installing MSE2 and it'll automagically download and install the new templates. Then you should be able to open up the .mse-set file and have all sorts of fun.
Did you know that MSE2 has a statistics page? I didn't before now, but with 65k generated cards to analyse, it's all sorts of fun. It'll also auto-expand keywords (a bit overzealously, if a keyword is part of the name of the card).
So go generate a few hundred cards from a checkpoint, export to a set file, and enjoy opening it in an actual card editor rather than inconvenient-to-read text Hopefully this means we get more awesome card images here.
edit: I had to include this gem of a card that I generated:
Bombers of the Baskery (rare) 2W
Creature ~ Human Monk
Bombers of the Baskery can't be blocked except by creatures with power 3 or greater.
Dash R
(3/3)
I attached a card image for this one as well. I soooo wish it didn't have the 's' and they were monks that bombed bakeries. Without the dash cost it's a good rare. With that dash cost it's wayyy over powered, but I really like that the dash cost is colour appropriate.
genju of the guildhatch (A) 4BB
legendary creature ~ spirit
flying, trample
at the beginning of each upkeep, put a +1/+1 counter on @.
threshold ~ @ enters the battlefield with two +1/+1 counters on it. 2, remove a +1/+1 counter from @: put a +1/+1 counter on target creature.
(6/6)
Holy crap. How did it manage to maintain such cohesion across three separate abilities?
I'm just having fun generating and viewing cards in MSE now. Expect this post to be updated with awesome new images. Such as...
Now that's a dragon-y dragon. Its second ability even seems like an alternate-Devour, kind of. But it's big, flying, devours and has RRR, so I'd say the network knows it's dragons (usually).
edit: anyone know how to resize embedded images? Full-res is nice, but it could also be 3/4 the size and perfectly readable.
edit2: @Talcos, what would I have to do to set up a flavour-text generation network alongside the card-generation one? I'd really like these cards to have some flavour, now that they're full images and all.
edit2: @Talcos, what would I have to do to set up a flavour-text generation network alongside the card-generation one? I'd really like these cards to have some flavour, now that they're full images and all.
Wow! Goregeous! I love it!
As for flavor, sure, it can be done. Question: Do you care whether the flavor text correlates with the cards? If you don't care, then it's easy because you can take a flavor-generating network checkpoint, have your generated cards in one hand and a list of flavor texts in the other and then you can just stitch them together. Now, if you want a flavor-text that somehow matches up with with the card, we'll need a scheme to do that or to generate flavor text for specific cards, and I haven't done that yet (though I have described schemes for doing so in earlier posts).
Alternatively, you could seed the flavor-generating network with a few starting words generated according to some formula. Like it's a dragon, so you could do...
Some dragons emerge from the moment of nature remained the blessing of the Divine.
Some dragons only converge.
Some dragons only knew what a price of Jingzha. Only a thinfly comes at a heart.
Some dragons emerge from Jund a slave-not system before anyone can make any choice.
Some dragons only knew was the once thing stand with mercy and less fine as dread.
Some dragons only knew what a prize rattles of the skyknights gather to create.
Some dragons really keep sure his heart and defenseless or the way.
Some dragons emerge from the enemy's appendages of silver and old age.
Some dragons only knew is too small to do that your fire?
Some dragons really know you.
And so on.
EDIT: Oh, I have a fun one, priming with "\"Dragons ":
"Dragons are just power. You why I willing twice as brood upon you hast meet where the Elvish desire always between."
- William Shakespeare, King Henry the Eighth
Notice it used the word "hast" and not "has", in an attempt to imitate Shakespeare. That is too good.
"Dragons are beasts. The Ghost Sultain welcomes the owneds of war enough to shape. Now I felt in ravens, hoping the spirit will survive a party."
- Volin, master wizard
EDIT(2): I'm sure the flavor text would improve considerably if we fed the network a few fantasy novels.
genju of the guildhatch (A)
4BB
legendary creature ~ spirit
flying, trample
at the beginning of each upkeep, put a +1/+1 counter on @.
threshold ~ @ enters the battlefield with two +1/+1 counters on it.
2, remove a +1/+1 counter from @: put a +1/+1 counter on target creature.
(6/6)
Holy crap. How did it manage to maintain such cohesion across three separate abilities?
Oh, it's quite capable of doing that when it feels like it. And it's interesting how it presents several layered chains of reasoning:
genju -> spirit -> flying
4bb -> 6/6 -> trample
Put counters on it at upkeep -> remove with ability
Enters with counters -> remove with ability
But honestly, part of the reason why cards don't usually look like that is actually deliberate. In theory, the network could go on enumerating a card forever, with one ability inspiring the next. The reason why it doesn't is because it's trying to emulate what actual cards look like, and one quality that the real cards have is that they have an average size of 140-150 characters. Such self-limiting behaviors are a healthy thing, but it does unintentionally curtail one-card combos like this more often than not.
Telcos, you said you were using mana costs to develop your color classifier. Have you considered using color identity instead?
It seems to me that your classifiers might see a creature with "GG: @ gains trample until end of turn" and classify it as a green card, because it mentions trample. In reality, this card could be mono-blue, or any other color(s).
Actually, it might be best to strip out off-color abilities altogether, and run them through their own classifier. Otherwise your classifier might still accept cards like:
Green Flier
3G
Creature ~ Beast
Flying
UU: @ gains trample until end of turn.
The generator may be smart enough to avoid this, but the order-agnostic classifier might let it through.
I'd like to feed the flavour generator the name of the card for which the flavour would be generated, yes. That may not always work out too well, but we can edit those down. If possible, I'd want the flavour text to be output into the same file as the cards are, so it's easier to format the result.
I really like the line "Some dragons really know you", personally. Sounds like that'd be a good one for Ojutai or someone.
This guy is probably OP; pay 5cmc, and draw 2 cards every time he damages. Nice to see the network getting Kicker right (in 6000+ cards that I generated, it only occurred in about 20, and occurred correctly only twice...)
Couldn't find a good image for this one. Also probably OP. The name is somewhat poetic, I thought, and matches nicely with the mechanic.
Really like the graveyard clause on this one. Your opponent probably won't want to kill it for that exact reason... but if it's alive, it's a 6/6 trampling flyer.
The wording is a bit off, but I enjoy the concept of a creature that could be a 2/2, or a 3/3 if you flip a coin right. And your opponent won't know until it's too late.
Bombers of the Baskery (rare) 2W
Creature ~ Human Monk
Bombers of the Baskery can't be blocked except by creatures with power 3 or greater.
Dash R
(3/3)
This isn't even that far off in terms of mana cost. I'm not even convinced its unprintable as is. Potent, but if Goyf is allowed.... If it is under costed, its only the dash cost that's under costed, and only by a mana or two. That's pretty impressive.
Private Mod Note
():
Rollback Post to RevisionRollBack
Every time I read a comment about "Well if this card had card draw/trample/haste/indestructible/hexproof/life gain...", I think "You're missing the point." They're armchair developer comments that fail to take into account the card's role in the greater Limited and Standard environment. No, it may not be as good as whatever card you're comparing it to. There's a reason for that. Not every burn spell is Lightning Bolt, nor does it need to be or should be.
- Manite
I've improved the decoder's MSE2 file output, and also put it in my own git repo where you can download it. It can now handle planeswalker cards, and choice cards are formatted nicely and such things. I should point out; due to the imperfect nature of the NN's output, I can't expect to have perfectly-formatted cards 100% of the time when this script runs. I aim for 99.9% of cards to be good, so only a few need the odd manual tweak here or there.
@Talcos, what scripts and checkpoints are you using for card generation these days? I presume it's sample_hs_v3, but I'm not sure which checkpoint it is. I'd like to generate a few hundred cards and import them straight into MSE2
Oh, someone mentioned MSE2 only being for Windows... I think that's strictly true, but I believe the WINE emulator can get around that for us (not tried that though).
Whats an enlightermancer?
So if the first pass produced "Mointainspalking Dragon|...|Flying\When ~ enters..." then prime it with "Mointainspalking Dragon|...|Delve\F" and hopefully it will continue with "lying..." (but what it does next will take both Delve and Flying into account).
Right now it's sample_hs_v3.lua for sampling. At some point in the future I might come out with a more robust sampling script, but it does decently at the moment.
As for the latest checkpoint, you can download it here.
However, I'll warn you that it's a GPU checkpoint, not a CPU one, and I'm still having problems with the latest version of char-rnn when I try to convert it over to CPU format. I get an error due to a float/double conversion issue. When I train a new network it'll be with the latest version of char-rnn, and this won't be an issue.
The machine churns out more questions than it does answers.
It looks like enlightened/enlightenment (the network learned that word from cards like Temple of Enlightenment and Isao, Enlightened Bushi) with the ending -mancer added on. The network likes to give creatures names that indicate agency. If I run the network and prime it with "wild enlight" for the name of the card, creature cards get names like...
* Wild Enlightermancer
* Wild Enlighter
* Wild Enlightener
* Wild Enlightermator (like Cragganwick Cremator)
* Wild Enlighterer
* Wild Enlightermare (like Thundermare)
* Wild Enlighterm (like Blastoderm or Tephraderm)
Nearly all of these creatures made by the network are white and a minority are blue, and they're almost all wizards, soldiers, and clerics. What's interesting is that if I take out "wild" so that the network is free to make "enlight" be an adjective or a noun, I get cards like
* Enlightened Unicorn
* Enlightened Dragon
* Enlightened Behemoth
* Enlightened Torturer
The colors are all over the place, as are the creature types.
As for what "Wild Enlightermancer" really means, I suspect its that the creature operates by producing wondrous ephinanies. Specifically, they know where an enemy is going to be standing five seconds from the present moment, which is why the creature has first strike. And because it's an enlightermancer, one who operates on sudden, miraculous revelations, the card has the miracle ability. There, a complete justification for the card from top to bottom.
Absolutely. The only problem is that we'd need to reformulate how we do the generation script because things you prime upstream affect things that get generated downstream, sometimes in subtle ways.
For instance, say you have this card:
Angelic Angel
3WW
Creature - Angel (Uncommon)
Flying
1W: Prevent the next 1 damage that would be dealt to target creature or player this turn.
4/4
Say you want the angel to have first strike, and you don't want to overwrite anything, so you isolate what comes before (flying) and after (the activated ability). You insert first strike, and right now the card looks like this:
Angelic Angel
3WW
Creature - Angel (Uncommon)
Flying, first strike
4/4
Because at this point the network doesn't know that the activated ability is going to be added back in, it's likely going to want to put in a new and different ability. Unless you do something to stop it, you'll end up with this card:
Angelic Angel
3WW
Creature - Angel (Uncommon)
Flying, first strike
Whenever Angelic Angel deals combat damage to a player, that player skips his or her next combat phase.
1W: Prevent the next 1 damage that would be dealt to target creature or player this turn.
4/4
So there are some challenges there with getting the logic just right so that we avoid cluttered cards. But yeah, it can be done. Very good suggestion.
EDIT: I feel like we're getting very close to our first draft. Just a few more things here and there and we should be set.
My LinkedIn profile... thing (I have one of those now!).
My research team's webpage.
The mtg-rnn repo and the mtg-encode repo.
For example, lets take the pseudocommand "zone.Change(target; origin; destination)".
"Exile target creature" could be written in the form "zone.Change(creature; battlefield; exile)"
"Return target artifact or enchantment card from a graveyard to its owner's hand would be written as zone.Change(artifact, enchantment; graveyard; hand)
Suddenly, the NN gets explicit information about the parallels between effects, and can make better educated guesses about the creative leaps it tries.
I then found this post on an old project to simulate MTG: http://www.goblinopera.com/mathemagics/?tag=mgl-parser
The post talks about the parser his program uses to makes sense of card text, and it's very close to what I was envisioning.
Would this syntax help the NN understand the rules better? Would it lead to creative stifling instead? Open the door to curious new effects? Promote overfitting? I'd love to hear thoughts and arguments.
Corbin Dallas multipaaaaass!
Honestly, I think an object-oriented approach to generating cards would be immensely beneficial. By reducing the syntactic complexity of each phrase as far as possible (essentially replacing each game term with a symbol), you eliminate the possibility of garbled outputs.
The only real possible downside is that a network trained in this manner might be less flexible in creating novel abilities. However, I think that comes down to how granular the encoding is.
Salut! Everything you've said is very, very interesting to me. Which reminds me, I really want to read your MSc dissertation when you finish, haha.
And thank you for sharing! I have to run for now, but I'll need to take a look at that later.
---
So I added in some syntax checks and a few semantics checks to the set construction script to eliminate garbage cards. It's a temporary fix until I can come up with a more robust solution. It gets rid of many mangled language problems (not all), and semantic issues like "kicked" without "kicker", inappropriate uses of "X", etc. I also threw in some temporary rules to excise creatures like slivers since we're working with a set that does not have slivers at all, and stuff like getting rid of transform creatures since I only grab the front face of those cards (I'll fix that at some point in the future). Overall, 24% of cards were eliminated on average from each set (that's roughly how much garbage there is in every dump).
I didn't attempt to eliminate any superfluous restrictions/actions, like activation restrictions on triggered abilities, or unnecessary shuffling. I figured that if we could just do that on our own.
There's also some unavoidable problem cards that have pointless qualities like this one:
Salt Rock Horror
3BB
Creature - Horror (uncommon)
Whenever Salt Rock Horror deals combat damage to a player, put a +1/+1 counter on it.
Remove a +1/+1 counter from Salt Rock Horror: put a +1/+1 counter on Salt Rock Horror.
(3/3)
They're rare and next to impossible to eliminate automatically because they're syntatically perfect and their abilities are appropriate for their colors. Our AI doesn't actually know how Magic is actually played so it isn't going to understand that Salt Rock Horror's ability isn't tactically useful.
Sample cards from the latest run for your entertainment (three mythics and two uncommons):
someone, martyr of kaldra (Y)
4WG
legendary creature ~ human wizard
vigilance, haste
when @ enters the battlefield, @ deals 3 damage to target creature or player.
whenever a creature enters the battlefield under your control, you may draw a card.
(4/3)
someone, worldwaker (Y)
1UB
legendary creature ~ human artificer
whenever @ deals combat damage to a player, that player sacrifices a creature. that player loses 1 life.
dredge 3
(2/2)
someone, archery (Y)
6RG
legendary creature ~ human wizard
T: destroy target artifact or enchantment.
delve
(1/1)
Minister of the Fire
2R
Creature - Human Shaman (Uncommon)
When Minister of the Fire enters the battlefield, it deals 2 damage to each creature without flying and each player.
2/2
#Everything must burn!
Angel's Glory
1G
Sorcery (Uncommon)
Search your library for a creature card with converted mana cost 2 or less and put it onto the battlefield. Then shuffle your library.
You can see the latest set here (and comment on anything if you'd like):
https://docs.google.com/document/d/1f09jZKii3U9-cnrZeuadxaeiJS4mpZjr79jMf2fNveA/edit?usp=sharing
As I'm sure you can see, there are cards here and there that'd need work. And if a card seems to totally unworkable, we could pick another one from one ourselves from the card dumps, which you can find here:
https://drive.google.com/file/d/0BxF7G2b8kigCNHp2S1lVY0tBeEk/view?usp=sharing
EDIT: I'm not saying this has to be the set we go with, but it's worth investigting whether or not it's workable at this point.
My LinkedIn profile... thing (I have one of those now!).
My research team's webpage.
The mtg-rnn repo and the mtg-encode repo.
Guys, if GoblynQueene's project and Talcos's project play well together, the result could be worth some real cheddar. The ability to churn out countless cards that are not only valid but actually based on an understanding of the Comprehensive Rules... The implications are staggering.
A network that understands the game's rules will be able to parse the difference between a useful ability and a drawback, which means that it won't look at Juzám Djinn and decide that 2BB for a 5/5 with "at the beginning of your upkeep, draw a card" is equally valid as 2BB for a 5/5 with "at the beginning of your upkeep, @ deals 1 damage to you."
A network that understands the rules will be able to make the distinction between permanents, spells, and players, so we don't get any "destroy target player" effects or sorceries that give themselves +1/+1 counters.
Just imagine what Wizards could do with something like that. Running on a top-end supercomputer, they could input a set of parameters ("make a bunch of Vampires," "design a 263-card set with a heavy graveyard theme," etc.) and crank out hundreds of thousands of perfectly valid cards every single day - more than they'd ever have time to actually look at.
They could then have their internal playtesters run drafts of the network-generated sets just to see what crazy mechanics it came up with and note what players liked the most, then run with it in human-designed sets down the line.
1UU
creature ~ human wizard
UU, T: you may put a creature card from your hand onto the battlefield. if you do, search your library for a creature card, reveal it, and put it into your hand. if you do, shuffle your library.
dredge 2
(2/2)
#I'll take "'I win' buttons" for $1,000, please, Alex.
3U
creature ~ serpent
flying
when @ enters the battlefield, sacrifice it unless you discard an artifact card.
threshold ~ as long as seven or more cards are in your graveyard, @ gets +X/+X, where X is your life total.
when @ dies, put a 3/3 green ape creature token onto the battlefield.
(3/3)
0.o blue Serra Avatar for 4 CMC
Here's my old posts regarding the actual decode.py script usage, download location and such:
All you have to do is use the -mse flag when exporting, for example:
py decode.py bigOldTextFileFullOfCards.txt mseCards -v -mse --norarity
In this case, it'll create a file called 'mseCards.mse-set' because that's the output file name we gave it.
To open this, you obviously need Magic Set Editor 2. You'll also need the m15 templates which don't come as default (for some daft reason). Click that link after installing MSE2 and it'll automagically download and install the new templates. Then you should be able to open up the .mse-set file and have all sorts of fun.
Did you know that MSE2 has a statistics page? I didn't before now, but with 65k generated cards to analyse, it's all sorts of fun. It'll also auto-expand keywords (a bit overzealously, if a keyword is part of the name of the card).
So go generate a few hundred cards from a checkpoint, export to a set file, and enjoy opening it in an actual card editor rather than inconvenient-to-read text Hopefully this means we get more awesome card images here.
edit: I had to include this gem of a card that I generated:
Bombers of the Baskery (rare)
2W
Creature ~ Human Monk
Bombers of the Baskery can't be blocked except by creatures with power 3 or greater.
Dash R
(3/3)
I attached a card image for this one as well. I soooo wish it didn't have the 's' and they were monks that bombed bakeries. Without the dash cost it's a good rare. With that dash cost it's wayyy over powered, but I really like that the dash cost is colour appropriate.
4BB
legendary creature ~ spirit
flying, trample
at the beginning of each upkeep, put a +1/+1 counter on @.
threshold ~ @ enters the battlefield with two +1/+1 counters on it.
2, remove a +1/+1 counter from @: put a +1/+1 counter on target creature.
(6/6)
Holy crap. How did it manage to maintain such cohesion across three separate abilities?
Now that's a dragon-y dragon. Its second ability even seems like an alternate-Devour, kind of. But it's big, flying, devours and has RRR, so I'd say the network knows it's dragons (usually).
edit: anyone know how to resize embedded images? Full-res is nice, but it could also be 3/4 the size and perfectly readable.
edit2: @Talcos, what would I have to do to set up a flavour-text generation network alongside the card-generation one? I'd really like these cards to have some flavour, now that they're full images and all.
Wow! Goregeous! I love it!
As for flavor, sure, it can be done. Question: Do you care whether the flavor text correlates with the cards? If you don't care, then it's easy because you can take a flavor-generating network checkpoint, have your generated cards in one hand and a list of flavor texts in the other and then you can just stitch them together. Now, if you want a flavor-text that somehow matches up with with the card, we'll need a scheme to do that or to generate flavor text for specific cards, and I haven't done that yet (though I have described schemes for doing so in earlier posts).
Alternatively, you could seed the flavor-generating network with a few starting words generated according to some formula. Like it's a dragon, so you could do...
and get texts like
And so on.
EDIT: Oh, I have a fun one, priming with "\"Dragons ":
"Dragons are just power. You why I willing twice as brood upon you hast meet where the Elvish desire always between."
- William Shakespeare, King Henry the Eighth
Notice it used the word "hast" and not "has", in an attempt to imitate Shakespeare. That is too good.
"Dragons are beasts. The Ghost Sultain welcomes the owneds of war enough to shape. Now I felt in ravens, hoping the spirit will survive a party."
- Volin, master wizard
EDIT(2): I'm sure the flavor text would improve considerably if we fed the network a few fantasy novels.
Oh, it's quite capable of doing that when it feels like it. And it's interesting how it presents several layered chains of reasoning:
genju -> spirit -> flying
4bb -> 6/6 -> trample
Put counters on it at upkeep -> remove with ability
Enters with counters -> remove with ability
But honestly, part of the reason why cards don't usually look like that is actually deliberate. In theory, the network could go on enumerating a card forever, with one ability inspiring the next. The reason why it doesn't is because it's trying to emulate what actual cards look like, and one quality that the real cards have is that they have an average size of 140-150 characters. Such self-limiting behaviors are a healthy thing, but it does unintentionally curtail one-card combos like this more often than not.
My LinkedIn profile... thing (I have one of those now!).
My research team's webpage.
The mtg-rnn repo and the mtg-encode repo.
It seems to me that your classifiers might see a creature with "GG: @ gains trample until end of turn" and classify it as a green card, because it mentions trample. In reality, this card could be mono-blue, or any other color(s).
Actually, it might be best to strip out off-color abilities altogether, and run them through their own classifier. Otherwise your classifier might still accept cards like:
Green Flier
3G
Creature ~ Beast
Flying
UU: @ gains trample until end of turn.
The generator may be smart enough to avoid this, but the order-agnostic classifier might let it through.
I really like the line "Some dragons really know you", personally. Sounds like that'd be a good one for Ojutai or someone.
... depends on the fantasy novels.
"The dragon spanked her harshly. 'You are my property,' it hissed."
Okay, who's been feeding the network Gor books?
MtG novels and Uncharted Realms, of course!
EDIT: Planeswalker's Guides too.
This guy is probably OP; pay 5cmc, and draw 2 cards every time he damages. Nice to see the network getting Kicker right (in 6000+ cards that I generated, it only occurred in about 20, and occurred correctly only twice...)
Couldn't find a good image for this one. Also probably OP. The name is somewhat poetic, I thought, and matches nicely with the mechanic.
Really like the graveyard clause on this one. Your opponent probably won't want to kill it for that exact reason... but if it's alive, it's a 6/6 trampling flyer.
The wording is a bit off, but I enjoy the concept of a creature that could be a 2/2, or a 3/3 if you flip a coin right. And your opponent won't know until it's too late.
This isn't even that far off in terms of mana cost. I'm not even convinced its unprintable as is. Potent, but if Goyf is allowed.... If it is under costed, its only the dash cost that's under costed, and only by a mana or two. That's pretty impressive.
- Manite