While the explicit formulation of rules for a game are copyrightable, the rules themselves cannot be.
To be slightly more specific - only text and images are copyrightable. So the specific rules (the text of the rules) and any art in the game can be copyrighted. But if you wrote a version of the rules that would pass a plagiarism test, even if the game played identically, it wouldn't violate copyright. Patent is a different issue, though I believe all of Magic's patents have expired.
You guys mentioned someone was working on a set of these?
Ah, yes, Elseleth has been. The original hope was to have a draft around labor day, but he ended up being very busy and to my knowledge the draft has yet to be held. I've been meaning to contact him about that, but then again, I've been very busy myself, haha. The set is more or less done, though I'm sure it could use some more art and flavor work, that sort of thing.
Right. I'd targeted Labor Day because I went on a trip last week where there was to be a board and card games night, but didn't get everything together in time. It turns out I likely wouldn't have gotten to run a draft anyway, because the games night was overwhelmingly dominated by party games like Cards Against Humanity--I don't think the crowd was quite geeky enough for robo-Magic.
I'm planning to polish up the set Talcos and I were working on, then maybe start in on another cube with the lessons learned from that experience. Maybe by then there will be an even sharper card-production process! I don't know when I'll get the chance to run a draft for real now, though, because most of my PnP RPG friends are lukewarm on the idea, and I'm not sure I want to jump feet-first into the local MtG scene at the moment.
While the explicit formulation of rules for a game are copyrightable, the rules themselves cannot be.
To be slightly more specific - only text and images are copyrightable. So the specific rules (the text of the rules) and any art in the game can be copyrighted. But if you wrote a version of the rules that would pass a plagiarism test, even if the game played identically, it wouldn't violate copyright. Patent is a different issue, though I believe all of Magic's patents have expired.
Right. I'd targeted Labor Day because I went on a trip last week where there was to be a board and card games night, but didn't get everything together in time. It turns out I likely wouldn't have gotten to run a draft anyway, because the games night was overwhelmingly dominated by party games like Cards Against Humanity--I don't think the crowd was quite geeky enough for robo-Magic.
Aha, gotcha. I figured that it was some combination of factors like that.
I'm planning to polish up the set Talcos and I were working on, then maybe start in on another cube with the lessons learned from that experience. Maybe by then there will be an even sharper card-production process! I don't know when I'll get the chance to run a draft for real now, though, because most of my PnP RPG friends are lukewarm on the idea, and I'm not sure I want to jump feet-first into the local MtG scene at the moment.
Fun.
A cube seems like a very good idea, actually. The network can churn out cool and interesting cards by the boatload, and designing for a cube would play to its strengths. So even if the draft doesn't end up happening, you can still put the ink and paper to use to produce something entertaining.
Just leaving this chess playing deep learner here. While not much of a content generating network the idea behind it, recognizing positions/patterns and narrowing down possible solution trees could be a good start for a NN that recognizes new cards their value and possible combo worthyness including the creation of "strategies". The potential treasuretrove of recorded MTG games from turnaments to online-games to train on could make, in the distant future, the perfect customer for "RoboRosewater"
What a coincidence, I was just looking at that master's thesis. It does present a lot of good strategies.
It can compete with "middle of the pack" chess-playing programs like Crafty, which is very promising. It doesn't perform as well as the high-end programs, but then again, a lot of the performance difference comes from sophisticated tricks to get the most out of the hardware rather than differences in the chess-playing algorithm itself (though there are some). My office is several doors down from the inventor of Crafty, so I've been acquainted with what goes on in the competitive AI chess scene.
Now, the approach that Lai uses is a stateless, feed-forward network (see diagram). That is, it doesn't have any permanent memory of what's going on, all of that is handled by a hand-crafted framework that is built around the use of the network. This is different than when Deepmind showed us could teach a network to play Atari games, because pretty much all of the decision-making was handled in the network in that case. Rather, Lai uses the network as a lantern to illuminate the dark state space, and makes his chess decisions based on what it reveals.
What's most impressive about the work is that he cuts out a manually programmed chess move evaluator and puts in a relatively primitive network in its place and it does just as well.
Of course, I have a feeling that more is needed for Magic, simply because the rules for chess are fixed, but new rules are introduced to Magic with every expansion. What you need is a system that is robust enough that you can throw completely new Magic cards at it and it can understand what they are and what they do, etc. without the need for human intervention. We're not quite there yet, but I have a feeling that we are pretty close. The limitations for Magic show up in a lot of other complex problem domains, and there's a ton of research being done right now to break through those barriers.
---
EDIT: Just for fun and because I haven't done it in awhile, I fired up the generator and seeded it with abilities from the upcoming set (I phrased everything as an ability word so I could feed the reminder text). Here are some fun results I got (at a temperature of 1, so the results are a little silly):
Steel of Ideal 7
Creature - Eldrazi (Uncommon)
Devoid
Ingest
Steel of Ideal has all activated abilities of red or green creatures.
6/6
Titanic Visitor W
Creature - Human Ally (Common)
[i]Rally[/i] - Whenever Titanic Visitor or another Ally you control enters the battlefield, sacrifice a creature. If you do, flip Titanic Visitor.
// //
Bright Shoden
Creature - Human Ally
[i]Rally[/i] - Whenever Bright Shoden or another Ally you control enters the battlefield, put a +1/+1 counter on target creature.
1/1
Mammoth of Souls 1W
Creature - Human Ally Wizard (Uncommon)
[i]Rally[/i] - Whenever Mammoth of Souls or another Ally you control enters the battlefield, flip a coin. If you win the flip, the next time a source of your choice would deal damage this turn, prevent that damage.
1/1
Browstom GG
Creature - Human Ally Tapper (Rare)
[i]Rally[/i] - Whenever Bright Shoden or another Ally you control enters the battlefield, put a 3/3 white Dragon artifact creature token with plainswalk onto the battlefield.
2/1
#Yes, the creature type is "tapper".
Wind of the Nantuko 3R
Creature - Shapeshifter (Rare)
[i]Converge[/i] - When Wind of the Nantuko enters the battlefield, for each color spent to cast it, put a 3/1 red Goblin creature token with defender named Hat Kithkin onto the battlefield.
3/3
#Okay then.
Gerrard's Eye 1G
Instant (Uncommon)
[i]Converge[i] - For each color of mana spent to cast Gerrard's Eye, put a +1/+1 counter on target creature.
#That's.. actually quite interesting. I like it.
Evil Pearl Tome xUU
Instant (Mythic Rare)
[i]Converge[i] - For each color of mana spent to cast Evil Pearl Tome, take an extra turn after this one.
#Wow. The X actually makes sense here. I'm surprised.
Pantemle
[mana]2u[mana]
Instant (Common)
For each color of mana spent to cast Pantemle, uncast target spell unless its controller pays 1.
Cipher
#How interesting. The cipher is useless though, isn't it?
Oh, and then there was these ones:
Volcanic Creaking 1R
Sorcery (Common)
Choose target creature. If you control your seat, exile that creature, then return it to the battlefield under its owner's control.
#Your seat? Where is it getting this wording from? It has to be getting it from somewhere. And under what circumstances does this spell do nothing? Many unanswered questions.
Temporal Eight 5UU
Sorcery (Rare)
Each player shuffles his or her hand and graveyard into his or her library, then draws seven cards. Then each player puts the top four cards of his or her library into his or her graveyard.
#I love the name "Temporal Eight". It really stuck out for me. It's unfortunate that this spell costs seven and draws seven cards.
Well, I'm building it up from neurons, but the goal is to have the interfaces go high-level. Like, the next function to define is one that takes an entire layer (note that there has to be a map sigmoid in here somewhere, but that's not very interesting), a size for the next layer, and produces "the next" layer from those specifications.
I see. So, in your design, if I have a layer, and I pass a vector of N values to a layer, one entry for each neuron, do you split up the incoming data N ways?
Regardless, in the end, whatever you do will be logically equivalent to what I do. I was just curious from a GPU parallelization perspective.
To be honest, I haven't really considered any kind of performance enhancements beyond "Let's see what the compiler does, given vanilla-y settings." I've tried to be sure that my code works before considering how I'm going to make it performant. So, I'm looking at what I have and thinking "Well, hypothetically, perhaps there's some kind of parallelization I could put into the evaluator functions." But, well... Python was giving me acceptable performance for what I was trying to do. I'm actually way more interested in putting together different architectures. (I don't remember how explicit I've been about the second architecture I want to implement, but, well, given the symbolic math types I've put together, there's nothing stopping me from putting together networks that reuse weights, which should allow me to prototype autoencoders that take variable-length input and convert it to a fixed-length encoded form, without having to do stuff like explicitly encode it as fixed-length. The other avenue it opens up is different training techniques, without having to work out, check and recheck all the dang math.)
Part of the reason I went for Haskell is that some of the stuff I was trying to tune is built into the language.
ETA: I would not be surprised if there's some pain at the beginning of testing this, just because some of the structures involved in my Haskell prototype are probably worse to use than the structures I was using in Python. But I want to see the naive case first, you know?
mwchase I know this is a bit late, but is what you're doing similar to Theano? Symbolic math, graph optimization, etc?
"A bit late." Heh, this port is barely started, really. Skimming the wiki makes it sound like using Theano for this would get me most of the stuff I was hand-writing and tuning, for free. I could certainly try it out.
I'd recommend it to anyone with python knowledge who is interested in jumping into machine learning. It has a bit of a steep learning curve, but I've had a ton of luck with it. There are also many really great libraries built on top of it to make it more user-friendly, my favorite being Lasagne.
EDIT: Just for fun and because I haven't done it in awhile, I fired up the generator and seeded it with abilities from the upcoming set (I phrased everything as an ability word so I could feed the reminder text).
I take it this is with an existing brain, not something produced by the new methodology you're working on?
EDIT: Just for fun and because I haven't done it in awhile, I fired up the generator and seeded it with abilities from the upcoming set (I phrased everything as an ability word so I could feed the reminder text).
I take it this is with an existing brain, not something produced by the new methodology you're working on?
Correct. I'm still waiting on the high-end machine to have the right libraries installed before I move forward with new, more interesting approaches.
EDIT: The results are a little unusual because I deliberately turned up the temperature in order to get more wild results, lol. Hence stuff like "if you control your seat".
... Huh. When I wrote up the network part of the autoencoder, I couldn't find any way to type the code in terms of the input size or hidden layer. So I've just got three functions that take input and matrices, and turn it into squared error/gradient/output.
Temporal Eight
5UU
Sorcery (Rare)
Each player shuffles his or her hand and graveyard into his or her library, then draws seven cards. Then each player puts the top four cards of his or her library into his or her graveyard.
#I love the name "Temporal Eight". It really stuck out for me. It's unfortunate that this spell costs seven and draws seven cards.
That actually works.
You see, astronomers number years starting from 0, so dates before year 1 are off by 1 from what you'd expect. It's a temporal eight (ie: seven), not a historical eight.
A cube seems like a very good idea, actually. The network can churn out cool and interesting cards by the boatload, and designing for a cube would play to its strengths. So even if the draft doesn't end up happening, you can still put the ink and paper to use to produce something entertaining.
A few things about it are easier, even: at least with a traditional "singleton" style cube, I don't need to pay overmuch attention to rarity, and needn't print off any more cards than are going to see use.
(Replying to the same post twice, my bad--I got distracted by the shiny RNN cards and didn't respond to this bit when I could've!)
Hey Talcos, dunno if you're aware of this paper, thought it might interest you somehow. From what I understood of it, it describes the use of a network architecture that is an hybrid of convolutional and recurrent networks (i.e. uses a bi-directional recurrent network to avoid windowing and benefits from having unbiased context to capture semantic meaning) and seems to do well at holding long-term context and holding dependencies.
Yeah, I've always been interested in the procedural generation scene, though in many ways I feel that the techniques that we're putting forward are a radical departure from the approaches used by that community. I'm not just targeting the content but also the underlying design; that's why Tyler Sigman asks "Wait a second, are robots taking our jobs?".
One of my favorite video games growing up was the Elder Scrolls game Daggerfall. Virtually everything in that game with the exception of the main storyline was procedurally generated: the terrain, the dungeons, the towns, the people, the quests - all of it. Eight-year-old me was absolutely fascinated by the idea that if you take a set of rules and a dash of randomness, you could unfold that into endless content. It's one of the experiences that steered me in the direction of computer science.
At the same time, I also felt a certain shallowness in it. When the designer creates the algorithms for the content, what they're doing is distilling their vision of that content into something that a computer can follow, and everything that the algorithm spits out is a parametrization or extrapolation of that vision. Now, that's not to say that the algorithm isn't creating novel content - it is. However, everything that the machine creates is locked in orbit around the creator's ideas.
And because of how algorithmic construction usually works, there's an unavoidable crudeness to it. Think of the vision as a circle, and the program, usually a hierarchical arrangement of if-else statements and boolean logic, is a polygon that approximates that circle. To make a good approximation, you need to have lots of rules (which translates into more sides on the polygon). The trick is to have enough diversity in the rules that it's hard to see the rough edges, but that takes a ton of work.
With our neural networks, we're approaching the problem from a different angle. Rather than trying to formalize the rules, instead we come up with examples that satisfy our vision, and we use that to train a system. The weights on our network constitute an algorithm for generating Magic cards, and (with regards to the circle/polygon analogy) the underlying architecture is adept at dealing with non-linearities, so it can do a much better job of approximating the smoothness and curviness. It can anticipate thousands of rules and relationships that we would not have even thought of but that are essential to our idea.
Furthermore, the model is easily extended. If you want to improve a hand-crafted procedural generator, you have to come up with more code. For us, we just have to show our network new examples and we can retrain it to produce new content.
Now, that's not to say that we're going to put procedural generation folks out of a job. Rather, what we can do is eliminate a lot of the drudgery, which frees them to pursue ever more ambitious designs.
---
EDIT: I'm still waiting for people to finish installing everything on the high-end machine. Hopefully not too much longer. In the mean time, a few choice cards from the network, this one trained on all Magic cards, sampled at a temperature of 1:
Keeper of the Ignitudes 3B
Creature - Human Horror (Rare)
When Keeper of the Ignitudes enters the battlefield, sacrifice it unless you sacrifice a land.
Creature spells you cast cost B less to cast.
1/1
#I'm not sure whether the drawback is really worth it if this comes down on turn four, but it's fun to think about.
Cabal Roo 4
Artifact (Uncommon)
Whenever a creature deals combat damage to an enchanted creature, destroy that creature.
Rebound
#The rebound is meaningless here, and it's a little ambiguous, but I kind of like what the card does.
Disensearch R
Instant (Common)
Untap all creatures you control.
#I just loved the word "disensearch". So much so that I primed with the name disensearch after seeing this card and got..
Disensearcher Priest 2RR
Creature - Human Barbarian (Uncommon)
When Disensearcher Priest dies, each player reveals the top card of his or hear library. You may play those cards instead.
3/3
#I think this needs an "until end of turn" clause.
Azumik's Herald 2B
Creature - Human Cleric (Uncommon) T, sacrifice Azumik's Herald: Search your library for a white card and put it onto the battlefield. then shuffle your library.
1/2
#She is the herald of Azumik, which could be a legendary creature of some sort. Or maybe Squire or Oblivion Ring. I'm honestly not sure. If I prime with the name Azumik, I can get...
Azumik, the Fortune Watcher 1W
Planeswalker - Karri (Uncommon)
+1: Untap target permanent.
3
#... a very tiny planeswalker. Or...
Azumik, the Strategic Archangel 4WW
Legendary Creature - Fox Monk (Rare)
Shadow
Azumik, the Strategic Archangel can't be blocked by Shades.
3/3
#Something like this. What a specific ability.
Hey Talcos, dunno if you're aware of this paper, thought it might interest you somehow. From what I understood of it, it describes the use of a network architecture that is an hybrid of convolutional and recurrent networks (i.e. uses a bi-directional recurrent network to avoid windowing and benefits from having unbiased context to capture semantic meaning) and seems to do well at holding long-term context and holding dependencies.
Sorry, missed your post earlier; we must have posted at around the same time.
Actually I have not seen this paper, interesting! And yes, your understanding of the work is correct.
I'm not sure how much we'd actually save/gain with with a word-level embedding simply because our formal Magic vocabulary is so small and formulaic, and a character-level model lets us introduce novel terms and phrases with ease. Now, embedding words in vectors like they're describing helps a ton when you have thousands and thousands of unique words; you can get past an author's particular word choice and get straight to the meaning, which is no doubt helpful for text classification.
Meanwhile, the use of a bidirectional approach seems really fun for a generative model, because the machine learns "To what extent does dragon imply firebreathing?" and also the reverse "to what extent does firebreathing imply dragon?". I could see that bearing fruit.
Honestly though, as far as I can tell, a lot of the problem of maintaining context over long distances boils down to being able to maintain a stable memory of that context. By reducing words in the text to vectors that capture the meaning of that word with respect to the surrounding words, they're shrinking the "distance" that the network has to travel, and by reading things bidirectionally, it strengthens and deepens the associations that the network can make.
But part of me thinks that you could do just as well if not better with a network that has mediocre memory but that has the foresight to write anything down that it's afraid of losing. You introduce the new problem of having to train the network to use that long-term storage and to remember where it wrote things down, but you have the advantage of being able to file unlimited amounts of information away and then pull it back into short-term memory whenever you need it. That's my current theory anyway.
Being able to forget stuff and move on is essential to short-term memory. It's a good thing. Without that, I doubt you'd be able to maintain the continuity of consciousness needed to read this post right now. But there's an inherent tension between the desire to forget and the need to retain long-term information, and that's something that we're investigating.
I'm finding that making a cube out of robocards is far more fun than filling out a set skeleton. There's no need for priming or filling "slots", so you're free to build in "greatest hits" fashion from whatever cards you want to work with. You still need to pay attention to things like balance across colors, mana curve, and ensuring equal access to removal, but it relieves a great deal of the trudge involved in searching for cards with very specific properties. Also, the cube mindset allows for continual tinkering as new cards--and new card-producing methodologies--come out!
I know I for one would love to play in a limited environment with fun stuff like this:
Pollenbright Wind (rare) GW
Instant
Each player returns all creature cards from his or her graveyard to the battlefield.
Patrol Fire (common) 1W
Instant
Put two 1/1 white human construct archer wizard all blue creature tokens with flying onto the battlefield.
Flashback 1W
Still no update on the software installations on the high-end machine. I'm probably going to ask for permission tomorrow to do the work myself given the slow pace of all this. I'm sitting on a stack of experiments ready to run and I need to move forward with them.
That and I have a positively radiant mosaic of Monestary Swiftspear for whom it would an injustice to delay a high resolution render any longer.
I'll get it all worked out.
By the way, I saw that the neuralstyle package was updated so that it is now possible to have multiple style images and blend them together. That way you can take a collection of works by a single artist and use those to get a better sense of the style of the artist, or to take different styles and blend them together. That should be fun.
By the way, I saw that the neuralstyle package was updated so that it is now possible to have multiple style images and blend them together. That way you can take a collection of works by a single artist and use those to get a better sense of the style of the artist, or to take different styles and blend them together. That should be fun.
Cool, I'll have to check that out.
I'm going to be trying to come up with a good param set using -optimizer adam, since it apparently is a pretty dramatic efficiency boost if you can get it to work.
By the way, I saw that the neuralstyle package was updated so that it is now possible to have multiple style images and blend them together. That way you can take a collection of works by a single artist and use those to get a better sense of the style of the artist, or to take different styles and blend them together. That should be fun.
Cool, I'll have to check that out.
I'm going to be trying to come up with a good param set using -optimizer adam, since it apparently is a pretty dramatic efficiency boost if you can get it to work.
I've heard good things about ADAM as well, and I made a post about it awhile back. However, I ran into issues with it when I was using it as an optimizer when training a Magic card generating network. Losses were going down until they hit an inflection point and skyrocketed back up, which I think was due to a poor choice of parameters on my part. But as for what the right set of parameters are for a given situation, I'm still not entirely sure. I may have to go back and look at that paper and see if they offer any clues. Let me know if you come up with any insights.
EDIT: I got a reply regarding the installation of Torch on the high-end machine. The man I need to do the job has been tied-up 24/7 getting a massive cluster of machines up and running for my colleagues over in information intelligence and forensics. I won't speculate on the exact nature of what they're using the cluster for (though I probably know the answer), but it's no doubt of great importance to the three-letter agency folks.
Before I got my new, more private office last winter, I had a desk over at their facility, and I had the opportunity to assist them with... various things. What I can say is that they are very talented people engaged in very complex problems, and they deserve all the time/resources/manpower that our department can spare.
That being said the work is just about done, and I'm going to be looking into getting Torch set up myself (to help move the process along), not sure if I'll need anyone to sign off on anything. At the very least, I'll definitely have everything up and running very early next week, but possibly sooner.
EDIT(2): Correction: much sooner. I now have admin access to the machine I want, so that eliminates the middleman.
EDIT(3): Things are looking good, but I'll have to look into some CUDA-related stuff. The CUDA libraries (version 7.5) are installed correctly, and Torch supports that version of CUDA as far as I know. I think I just need to make some minor changes to the configuration, which I'll take a look at later.
EDIT(4): Aha, I think I found the issue. I'm having to do everything in a docker container and the script I was using pulled in the wrong version of the CUDA library... for some unknown reason.
Current status on new architecture: had to fix some bugs that were in my code, but Theano kept implying were its fault. I'm running the training stuff now. So far, every error has come up nan.
"... But... can you extract sign information from it?"
"No." or "They're all negative."
Okay, so, the output and initial values are okay. That means I messed up training somewhere. All of my functions except training work, but training spews NaNs. Hrmph.
ETA: Kicked the training values way down. Getting promising results from a 40-HN network. The diagnostic code overflowed the screen, and there were errors, so I kicked up the iterations and had it dump the results, and the network state, to a file.
ETA: Didn't get the full network state. Oops. I can regenerate it, anyway.
We're seeing some typical off-by-power-of-two errors here. A factor of the way I've set up the network is that the beginning of the word is far more vulnerable to degradation than the end, though this is not a hard-and-fast rule. It's notable, I think, that it's having trouble both with the hyphen, and the internal capital in "Assembly-Worker". That name is notable for those characteristics, and its length. Because the name is an outlier, it may well be the last thing that this network gets right.
ETA: Waaait a sec... all of those results are without any sigmoids hooked it. Whoops.
ETA: Interesting. With sigmoids added, the overall error goes down, but there are way more discrepancies.
I'll have to see what happens if I crank the iteration count up.
ETA: I left the last run of the linear version to complete. It's capable of low discrepancies, but the error is persistently high:
Assembly-Worker: Assemblymworker
Jellyfish: Kellyfish
Manticore: ]anticore
I think I'd like to see what the non-linear version can do.
Ah. The error reports from the longer run reveal that that large number of misspellings came from a momentary spike in the error.
So, I am a undergraduate student from Brazil, and I have been following this thread for a while. Recently, I have been learning about Machine Learning because this subject has caught my attention a lot. I was part of a Call of duty clan when someone from this clan created a thread that talked about this thread here, so that's how I found you guys. I used play Magic the Gathering a lot when I was a kid, but now I don't even know the new abilities and features Magic might have.
Anyway, I came here today to say that I came up with this idea of using the algorithm you guys have used, to apply in that card game called Hearthstone. Apparently, Hearthstone seems to be simpler than Magic, so the modeling was also very simple. Basically, I used "card name", "mana cost", "type","text","attack","defense".
So, a card would be represented like this one below:
@Gleibeth from Kingdom Of Jeraynna | *^^^* | Minion | Transform a minion into a 4/10 creature that has the same type of this card. | {1} | #1#
I took some ideas from the type of modeling you guys have used.
The biggest problem I have had is that Hearthstone does not have as many cards as Magic has, so my data base is small. In order to solve this problem, I have created cards getting elves names that I have found in websites. Also, I have got "mana cost", "attack", and "defense" from Magic's cards. Doing this procedure, I have got this input that has 1.8MB, and believe me, it was hard to get to this amount.
The result was kinda interesting, I am going to paste here some of the cards that the network has created.
I know you guys know better about Magic, and this is the same for me, but I would like to ask if you guys have an idea that could help improving my results.
Actually hearthstone would be perfect for this. . . since it already uses random effects, those random effects could now be used to create brand new cards thanks to the machine generated cards
Anyway, I came here today to say that I came up with this idea of using the algorithm you guys have used, to apply in that card game called Hearthstone.
There is a popular reddit post here on that very topic that is a fun read.
As you have said, Hearthstone has a cripplingly tiny card pool for this kind of approach (681 if you count tokens and non-collectibles). It just isn't enough for there to be noticeable trends (moreso now thanks to the addition of cards that are strictly better than previous cards). That's not to say it won't work, it's just a much more difficult problem. As an avid Hearthstone player, I hope you get it to succeed!
Anyway, I came here today to say that I came up with this idea of using the algorithm you guys have used, to apply in that card game called Hearthstone.
There is a popular reddit post here on that very topic that is a fun read.
As you have said, Hearthstone has a cripplingly tiny card pool for this kind of approach (681 if you count tokens and non-collectibles). It just isn't enough for there to be noticeable trends (moreso now thanks to the addition of cards that are strictly better than previous cards). That's not to say it won't work, it's just a much more difficult problem. As an avid Hearthstone player, I hope you get it to succeed!
Actually it has a dedicated subreddit now, /r/Flamewanker
This is basically Hearthstone's Slidshocking Krow if you see what I mean.
Private Mod Note
():
Rollback Post to RevisionRollBack
To post a comment, please login or register a new account.
To be slightly more specific - only text and images are copyrightable. So the specific rules (the text of the rules) and any art in the game can be copyrighted. But if you wrote a version of the rules that would pass a plagiarism test, even if the game played identically, it wouldn't violate copyright. Patent is a different issue, though I believe all of Magic's patents have expired.
Custom Set
https://docs.google.com/spreadsheets/d/1hu9uNBSUt92PwGhvexYlwFvsh6_SJBlEEIUV3H9_XyU/edit?usp=sharing
I'm planning to polish up the set Talcos and I were working on, then maybe start in on another cube with the lessons learned from that experience. Maybe by then there will be an even sharper card-production process! I don't know when I'll get the chance to run a draft for real now, though, because most of my PnP RPG friends are lukewarm on the idea, and I'm not sure I want to jump feet-first into the local MtG scene at the moment.
True, good point.
Aha, gotcha. I figured that it was some combination of factors like that.
Fun.
A cube seems like a very good idea, actually. The network can churn out cool and interesting cards by the boatload, and designing for a cube would play to its strengths. So even if the draft doesn't end up happening, you can still put the ink and paper to use to produce something entertaining.
What a coincidence, I was just looking at that master's thesis. It does present a lot of good strategies.
It can compete with "middle of the pack" chess-playing programs like Crafty, which is very promising. It doesn't perform as well as the high-end programs, but then again, a lot of the performance difference comes from sophisticated tricks to get the most out of the hardware rather than differences in the chess-playing algorithm itself (though there are some). My office is several doors down from the inventor of Crafty, so I've been acquainted with what goes on in the competitive AI chess scene.
Now, the approach that Lai uses is a stateless, feed-forward network (see diagram). That is, it doesn't have any permanent memory of what's going on, all of that is handled by a hand-crafted framework that is built around the use of the network. This is different than when Deepmind showed us could teach a network to play Atari games, because pretty much all of the decision-making was handled in the network in that case. Rather, Lai uses the network as a lantern to illuminate the dark state space, and makes his chess decisions based on what it reveals.
What's most impressive about the work is that he cuts out a manually programmed chess move evaluator and puts in a relatively primitive network in its place and it does just as well.
Of course, I have a feeling that more is needed for Magic, simply because the rules for chess are fixed, but new rules are introduced to Magic with every expansion. What you need is a system that is robust enough that you can throw completely new Magic cards at it and it can understand what they are and what they do, etc. without the need for human intervention. We're not quite there yet, but I have a feeling that we are pretty close. The limitations for Magic show up in a lot of other complex problem domains, and there's a ton of research being done right now to break through those barriers.
---
EDIT: Just for fun and because I haven't done it in awhile, I fired up the generator and seeded it with abilities from the upcoming set (I phrased everything as an ability word so I could feed the reminder text). Here are some fun results I got (at a temperature of 1, so the results are a little silly):
Steel of Ideal
7
Creature - Eldrazi (Uncommon)
Devoid
Ingest
Steel of Ideal has all activated abilities of red or green creatures.
6/6
Titanic Visitor
W
Creature - Human Ally (Common)
[i]Rally[/i] - Whenever Titanic Visitor or another Ally you control enters the battlefield, sacrifice a creature. If you do, flip Titanic Visitor.
// //
Bright Shoden
Creature - Human Ally
[i]Rally[/i] - Whenever Bright Shoden or another Ally you control enters the battlefield, put a +1/+1 counter on target creature.
1/1
Mammoth of Souls
1W
Creature - Human Ally Wizard (Uncommon)
[i]Rally[/i] - Whenever Mammoth of Souls or another Ally you control enters the battlefield, flip a coin. If you win the flip, the next time a source of your choice would deal damage this turn, prevent that damage.
1/1
Browstom
GG
Creature - Human Ally Tapper (Rare)
[i]Rally[/i] - Whenever Bright Shoden or another Ally you control enters the battlefield, put a 3/3 white Dragon artifact creature token with plainswalk onto the battlefield.
2/1
#Yes, the creature type is "tapper".
Wind of the Nantuko
3R
Creature - Shapeshifter (Rare)
[i]Converge[/i] - When Wind of the Nantuko enters the battlefield, for each color spent to cast it, put a 3/1 red Goblin creature token with defender named Hat Kithkin onto the battlefield.
3/3
#Okay then.
Gerrard's Eye
1G
Instant (Uncommon)
[i]Converge[i] - For each color of mana spent to cast Gerrard's Eye, put a +1/+1 counter on target creature.
#That's.. actually quite interesting. I like it.
Evil Pearl Tome
xUU
Instant (Mythic Rare)
[i]Converge[i] - For each color of mana spent to cast Evil Pearl Tome, take an extra turn after this one.
#Wow. The X actually makes sense here. I'm surprised.
Pantemle
[mana]2u[mana]
Instant (Common)
For each color of mana spent to cast Pantemle, uncast target spell unless its controller pays 1.
Cipher
#How interesting. The cipher is useless though, isn't it?
Oh, and then there was these ones:
Volcanic Creaking
1R
Sorcery (Common)
Choose target creature. If you control your seat, exile that creature, then return it to the battlefield under its owner's control.
#Your seat? Where is it getting this wording from? It has to be getting it from somewhere. And under what circumstances does this spell do nothing? Many unanswered questions.
Temporal Eight
5UU
Sorcery (Rare)
Each player shuffles his or her hand and graveyard into his or her library, then draws seven cards. Then each player puts the top four cards of his or her library into his or her graveyard.
#I love the name "Temporal Eight". It really stuck out for me. It's unfortunate that this spell costs seven and draws seven cards.
My LinkedIn profile... thing (I have one of those now!).
My research team's webpage.
The mtg-rnn repo and the mtg-encode repo.
To be honest, I haven't really considered any kind of performance enhancements beyond "Let's see what the compiler does, given vanilla-y settings." I've tried to be sure that my code works before considering how I'm going to make it performant. So, I'm looking at what I have and thinking "Well, hypothetically, perhaps there's some kind of parallelization I could put into the evaluator functions." But, well... Python was giving me acceptable performance for what I was trying to do. I'm actually way more interested in putting together different architectures. (I don't remember how explicit I've been about the second architecture I want to implement, but, well, given the symbolic math types I've put together, there's nothing stopping me from putting together networks that reuse weights, which should allow me to prototype autoencoders that take variable-length input and convert it to a fixed-length encoded form, without having to do stuff like explicitly encode it as fixed-length. The other avenue it opens up is different training techniques, without having to work out, check and recheck all the dang math.)
Part of the reason I went for Haskell is that some of the stuff I was trying to tune is built into the language.
ETA: I would not be surprised if there's some pain at the beginning of testing this, just because some of the structures involved in my Haskell prototype are probably worse to use than the structures I was using in Python. But I want to see the naive case first, you know?
"A bit late." Heh, this port is barely started, really. Skimming the wiki makes it sound like using Theano for this would get me most of the stuff I was hand-writing and tuning, for free. I could certainly try it out.
Correct. I'm still waiting on the high-end machine to have the right libraries installed before I move forward with new, more interesting approaches.
EDIT: The results are a little unusual because I deliberately turned up the temperature in order to get more wild results, lol. Hence stuff like "if you control your seat".
My LinkedIn profile... thing (I have one of those now!).
My research team's webpage.
The mtg-rnn repo and the mtg-encode repo.
That actually works.
You see, astronomers number years starting from 0, so dates before year 1 are off by 1 from what you'd expect. It's a temporal eight (ie: seven), not a historical eight.
I'm going to have to work on making a good interactive mode for myself, maybe work in iPython, because the warmup time is killer.
On further inspection, this is actually the most accurate* net I've rolled so far with these parameters.
*Best convergence rate (by a nose)
(Replying to the same post twice, my bad--I got distracted by the shiny RNN cards and didn't respond to this bit when I could've!)
https://www.youtube.com/watch?v=S9pc8li4fuQ at 35:35
Haha, thanks for sharing.
Yeah, I've always been interested in the procedural generation scene, though in many ways I feel that the techniques that we're putting forward are a radical departure from the approaches used by that community. I'm not just targeting the content but also the underlying design; that's why Tyler Sigman asks "Wait a second, are robots taking our jobs?".
One of my favorite video games growing up was the Elder Scrolls game Daggerfall. Virtually everything in that game with the exception of the main storyline was procedurally generated: the terrain, the dungeons, the towns, the people, the quests - all of it. Eight-year-old me was absolutely fascinated by the idea that if you take a set of rules and a dash of randomness, you could unfold that into endless content. It's one of the experiences that steered me in the direction of computer science.
At the same time, I also felt a certain shallowness in it. When the designer creates the algorithms for the content, what they're doing is distilling their vision of that content into something that a computer can follow, and everything that the algorithm spits out is a parametrization or extrapolation of that vision. Now, that's not to say that the algorithm isn't creating novel content - it is. However, everything that the machine creates is locked in orbit around the creator's ideas.
And because of how algorithmic construction usually works, there's an unavoidable crudeness to it. Think of the vision as a circle, and the program, usually a hierarchical arrangement of if-else statements and boolean logic, is a polygon that approximates that circle. To make a good approximation, you need to have lots of rules (which translates into more sides on the polygon). The trick is to have enough diversity in the rules that it's hard to see the rough edges, but that takes a ton of work.
With our neural networks, we're approaching the problem from a different angle. Rather than trying to formalize the rules, instead we come up with examples that satisfy our vision, and we use that to train a system. The weights on our network constitute an algorithm for generating Magic cards, and (with regards to the circle/polygon analogy) the underlying architecture is adept at dealing with non-linearities, so it can do a much better job of approximating the smoothness and curviness. It can anticipate thousands of rules and relationships that we would not have even thought of but that are essential to our idea.
Furthermore, the model is easily extended. If you want to improve a hand-crafted procedural generator, you have to come up with more code. For us, we just have to show our network new examples and we can retrain it to produce new content.
Now, that's not to say that we're going to put procedural generation folks out of a job. Rather, what we can do is eliminate a lot of the drudgery, which frees them to pursue ever more ambitious designs.
---
EDIT: I'm still waiting for people to finish installing everything on the high-end machine. Hopefully not too much longer. In the mean time, a few choice cards from the network, this one trained on all Magic cards, sampled at a temperature of 1:
Keeper of the Ignitudes
3B
Creature - Human Horror (Rare)
When Keeper of the Ignitudes enters the battlefield, sacrifice it unless you sacrifice a land.
Creature spells you cast cost B less to cast.
1/1
#I'm not sure whether the drawback is really worth it if this comes down on turn four, but it's fun to think about.
Cabal Roo
4
Artifact (Uncommon)
Whenever a creature deals combat damage to an enchanted creature, destroy that creature.
Rebound
#The rebound is meaningless here, and it's a little ambiguous, but I kind of like what the card does.
Disensearch
R
Instant (Common)
Untap all creatures you control.
#I just loved the word "disensearch". So much so that I primed with the name disensearch after seeing this card and got..
Disensearcher Priest
2RR
Creature - Human Barbarian (Uncommon)
When Disensearcher Priest dies, each player reveals the top card of his or hear library. You may play those cards instead.
3/3
#I think this needs an "until end of turn" clause.
Azumik's Herald
2B
Creature - Human Cleric (Uncommon)
T, sacrifice Azumik's Herald: Search your library for a white card and put it onto the battlefield. then shuffle your library.
1/2
#She is the herald of Azumik, which could be a legendary creature of some sort. Or maybe Squire or Oblivion Ring. I'm honestly not sure. If I prime with the name Azumik, I can get...
Azumik, the Fortune Watcher
1W
Planeswalker - Karri (Uncommon)
+1: Untap target permanent.
3
#... a very tiny planeswalker. Or...
Azumik, the Strategic Archangel
4WW
Legendary Creature - Fox Monk (Rare)
Shadow
Azumik, the Strategic Archangel can't be blocked by Shades.
3/3
#Something like this. What a specific ability.
Sorry, missed your post earlier; we must have posted at around the same time.
Actually I have not seen this paper, interesting! And yes, your understanding of the work is correct.
I'm not sure how much we'd actually save/gain with with a word-level embedding simply because our formal Magic vocabulary is so small and formulaic, and a character-level model lets us introduce novel terms and phrases with ease. Now, embedding words in vectors like they're describing helps a ton when you have thousands and thousands of unique words; you can get past an author's particular word choice and get straight to the meaning, which is no doubt helpful for text classification.
Meanwhile, the use of a bidirectional approach seems really fun for a generative model, because the machine learns "To what extent does dragon imply firebreathing?" and also the reverse "to what extent does firebreathing imply dragon?". I could see that bearing fruit.
Honestly though, as far as I can tell, a lot of the problem of maintaining context over long distances boils down to being able to maintain a stable memory of that context. By reducing words in the text to vectors that capture the meaning of that word with respect to the surrounding words, they're shrinking the "distance" that the network has to travel, and by reading things bidirectionally, it strengthens and deepens the associations that the network can make.
But part of me thinks that you could do just as well if not better with a network that has mediocre memory but that has the foresight to write anything down that it's afraid of losing. You introduce the new problem of having to train the network to use that long-term storage and to remember where it wrote things down, but you have the advantage of being able to file unlimited amounts of information away and then pull it back into short-term memory whenever you need it. That's my current theory anyway.
Being able to forget stuff and move on is essential to short-term memory. It's a good thing. Without that, I doubt you'd be able to maintain the continuity of consciousness needed to read this post right now. But there's an inherent tension between the desire to forget and the need to retain long-term information, and that's something that we're investigating.
My LinkedIn profile... thing (I have one of those now!).
My research team's webpage.
The mtg-rnn repo and the mtg-encode repo.
I know I for one would love to play in a limited environment with fun stuff like this:
Pollenbright Wind (rare)
GW
Instant
Each player returns all creature cards from his or her graveyard to the battlefield.
Patrol Fire (common)
1W
Instant
Put two 1/1 white human construct archer wizard all blue creature tokens with flying onto the battlefield.
Flashback 1W
That and I have a positively radiant mosaic of Monestary Swiftspear for whom it would an injustice to delay a high resolution render any longer.
I'll get it all worked out.
By the way, I saw that the neuralstyle package was updated so that it is now possible to have multiple style images and blend them together. That way you can take a collection of works by a single artist and use those to get a better sense of the style of the artist, or to take different styles and blend them together. That should be fun.
My LinkedIn profile... thing (I have one of those now!).
My research team's webpage.
The mtg-rnn repo and the mtg-encode repo.
Cool, I'll have to check that out.
I'm going to be trying to come up with a good param set using -optimizer adam, since it apparently is a pretty dramatic efficiency boost if you can get it to work.
I've heard good things about ADAM as well, and I made a post about it awhile back. However, I ran into issues with it when I was using it as an optimizer when training a Magic card generating network. Losses were going down until they hit an inflection point and skyrocketed back up, which I think was due to a poor choice of parameters on my part. But as for what the right set of parameters are for a given situation, I'm still not entirely sure. I may have to go back and look at that paper and see if they offer any clues. Let me know if you come up with any insights.
EDIT: I got a reply regarding the installation of Torch on the high-end machine. The man I need to do the job has been tied-up 24/7 getting a massive cluster of machines up and running for my colleagues over in information intelligence and forensics. I won't speculate on the exact nature of what they're using the cluster for (though I probably know the answer), but it's no doubt of great importance to the three-letter agency folks.
Before I got my new, more private office last winter, I had a desk over at their facility, and I had the opportunity to assist them with... various things. What I can say is that they are very talented people engaged in very complex problems, and they deserve all the time/resources/manpower that our department can spare.
That being said the work is just about done, and I'm going to be looking into getting Torch set up myself (to help move the process along), not sure if I'll need anyone to sign off on anything. At the very least, I'll definitely have everything up and running very early next week, but possibly sooner.
EDIT(2): Correction: much sooner. I now have admin access to the machine I want, so that eliminates the middleman.
EDIT(3): Things are looking good, but I'll have to look into some CUDA-related stuff. The CUDA libraries (version 7.5) are installed correctly, and Torch supports that version of CUDA as far as I know. I think I just need to make some minor changes to the configuration, which I'll take a look at later.
EDIT(4): Aha, I think I found the issue. I'm having to do everything in a docker container and the script I was using pulled in the wrong version of the CUDA library... for some unknown reason.
My LinkedIn profile... thing (I have one of those now!).
My research team's webpage.
The mtg-rnn repo and the mtg-encode repo.
"... But... can you extract sign information from it?"
"No." or "They're all negative."
Okay, so, the output and initial values are okay. That means I messed up training somewhere. All of my functions except training work, but training spews NaNs. Hrmph.
ETA: Kicked the training values way down. Getting promising results from a 40-HN network. The diagnostic code overflowed the screen, and there were errors, so I kicked up the iterations and had it dump the results, and the network state, to a file.
ETA: Didn't get the full network state. Oops. I can regenerate it, anyway.
Basilisk: Jasilisk
Crocodile: Csocodile
Dreadnought: Ereadnought
Gargoyle: Oargoyle
Homunculus: Hoeunculus
Incarnation: Ancarnation
Jellyfish: Kellyfish
Nephilim: Oephilim
Nightstalker: Gightstalker
Phyrexian: @xyrexian
Shapeshifter: Siapashifter
Triskelavite: Psiskelavite
ETA: Here's another dump, and some analysis:
Brushwagg: Crushwagg
Construct: Cmnstruct
Incarnation: Ilcarnation
Nephilim: Lephilim
Nightstalker: Nighpstalker
Reflection: Peflection
Surrakar: Qurrakar
Wolverine: Wmlverine
ETA: Waaait a sec... all of those results are without any sigmoids hooked it. Whoops.
ETA: Interesting. With sigmoids added, the overall error goes down, but there are way more discrepancies.
Assembly-Worker CCCEnilqiworker
Badger Cadger
Bringer Cringer
Brushwagg Bsushwagg
Cockatrice CGCkatrice
Construct Constsuct
Crocodile Cvocodile
Dreadnought Dreatnought
Elemental elemental
Gargoyle Gargoqle
Hippogriff Hippmgriff
Homunculus Iomunculus
Incarnation Incapnation
Kitsune Katsune
Loxodon Loqodon
Nightmare Jightmare
Nightstalker Gaohtqtalker
Nymph Nimph
Oyster Oqster
Phyrexian Phirexian
Rabbit Sabbit
Rakshasas Rakrhasas
Saproling Sappoling
Scarecrow Ccarecrow
Thrull Tirull
Triskelavite Triqkelavite
Zubera Zufera
Treefolf tveevolf
ETA: I left the last run of the linear version to complete. It's capable of low discrepancies, but the error is persistently high:
Assembly-Worker: Assemblymworker
Jellyfish: Kellyfish
Manticore: ]anticore
I think I'd like to see what the non-linear version can do.
Ah. The error reports from the longer run reveal that that large number of misspellings came from a momentary spike in the error.
So, I am a undergraduate student from Brazil, and I have been following this thread for a while. Recently, I have been learning about Machine Learning because this subject has caught my attention a lot. I was part of a Call of duty clan when someone from this clan created a thread that talked about this thread here, so that's how I found you guys. I used play Magic the Gathering a lot when I was a kid, but now I don't even know the new abilities and features Magic might have.
Anyway, I came here today to say that I came up with this idea of using the algorithm you guys have used, to apply in that card game called Hearthstone. Apparently, Hearthstone seems to be simpler than Magic, so the modeling was also very simple. Basically, I used "card name", "mana cost", "type","text","attack","defense".
So, a card would be represented like this one below:
@Gleibeth from Kingdom Of Jeraynna | *^^^* | Minion | Transform a minion into a 4/10 creature that has the same type of this card. | {1} | #1#
I took some ideas from the type of modeling you guys have used.
The biggest problem I have had is that Hearthstone does not have as many cards as Magic has, so my data base is small. In order to solve this problem, I have created cards getting elves names that I have found in websites. Also, I have got "mana cost", "attack", and "defense" from Magic's cards. Doing this procedure, I have got this input that has 1.8MB, and believe me, it was hard to get to this amount.
The result was kinda interesting, I am going to paste here some of the cards that the network has created.
I know you guys know better about Magic, and this is the same for me, but I would like to ask if you guys have an idea that could help improving my results.
Cards:
@Gefrith | *^^^^^^* | Minion | Deathrattle: Sumon a minion 4/5 | {1} | #1#
@Aelongund | *^* | Minion | | {2} | #2#
@Falcontron | *^^^^^* | Spell | Deal $4 damage. Draw a card. | {3} | #2# ------------------->>>>> Spells should not have attack and defense
@Gleibeth from Kingdom Of Jeraynna | *^^^* | Minion | Transform a minion into a 4/10 creature that has the same type of this card. | {1} | #1#
@Summerpell | *^^^^^^^^^^* | Spell | Deal $2 damage to a minion. Give your minions and your weapon +1/+1. | {0} | #0#
@siberomor | *^^^^^^* | Minion | Raid Leadero's Surnemprill | *^^^^^^^^* | Spell | Deal $1 damage. | | -------------------------->>>> Funny
@Etelader | *^* | Minion | Your other Pirates have +1/+1. | {3} | #2#
@Whillcourt | *^^^^^^^^^^* | Spell | Shuffle a player's hand | |
@Rugali | *^^^* | Minion | Battlecry: Give a minion Windfury. | {1} | #1#
Sincerely,
Arthur Medeiros.
As you have said, Hearthstone has a cripplingly tiny card pool for this kind of approach (681 if you count tokens and non-collectibles). It just isn't enough for there to be noticeable trends (moreso now thanks to the addition of cards that are strictly better than previous cards). That's not to say it won't work, it's just a much more difficult problem. As an avid Hearthstone player, I hope you get it to succeed!
This is basically Hearthstone's Slidshocking Krow if you see what I mean.