Parser - Ideas for addition

All additions requested or suggested to improve the card coding language.
Post Reply
abrasax
Posts: 976
Joined: Wed Oct 15, 2008 7:46 am
Location: Switzerland

Parser - Ideas for addition

Post by abrasax »

Hi people,

I have thought a lot about the parser and the keywords in the last week, and I begin to have a more clear overview of what we could add or not. So here are my thought and I would like to begin a kind of brainstorming/ideas about what could be added to the parser, also we must keep in mind that if we add something the new function should be generic enough in order to allow us to add quite some cards to the cards.dat.

In the SVN I’ve added the deplete function which is a “millstone” function and also the “discard” (random discard in this case), but in the end there is not soo much card that are using this function, the same is true for rampage.

One function that appears a lot is a “triggered” function when a cards move from a zone to another, e.g. “when X is put in play” or “when X is put in the graveyard from play” or “when X is discarded” (also from hand to graveyard in this last case”. The effect are various and can be anything such as “discard:X target(Y)”, “destroy target(X)”, moveto( ) (most of the time, move back to hand), etc….

Another very widely use keyword in magic is “Whenever”, the issue here is that this is a condition, this condition can be of any kind for example:
“a player play a spell”, “you play a spell”, “target opponent play a spell”,”creature X you control attack”, “card type X is moving from zone Z to zone Y”…
Then you have the “effect”, this effect is sometime automatic, or may occurs, sometime for the payment of mana, these effect can also be of any kind
target creature get +X/+X, put a XXX token in play, You gain X life, damage X to target…etc..etc..
Some of this “whenever” have already been coded (e.g. whenever a player plays a COLOR spell you may gain X life), but most of them are too complex to be added to the parser in my opinion.

One thing that could be added in a “near” future, would be a damage for each function this is already existing in the code to one or the other extend. The only question that arises is how to write this functions in the parser.

It could be a function like “damageforeach”, but coding a function like “foreach(X) damage:Y” would be more complicated especially if you want to add a target like “foreach(X) damage:Y target(Z)” or if you want to add “all” like “foreach(X):damage:Y all(Z)”, if you want it to function with an activation cost then it becomes a nightmare.

I’ve look at this one but personally at the moment I’m stuck, I have to admit it is very complicated, although a lot of cards could be added to the cards.dat with this function (e.g. corrupt from USG, storm seeker and typhoon from LEG, Fire Dragon from POR, Inquisition from Dar, Sudden Impact from 10E, Chaotic Backlash from EVE, etc…)

Another one that could be possible is a “damage equal to power function, is think it could be added by simply adding the keyword “power” to the parser into the damage function, it would then return the value of the card power, also in the first time it would only be able to code the cards that gives damage equal to their power e.g. {T}:damage:power.

Lastly a one wololo mentioned some time ago is the “cantbeblockedby(target)” and the “cantblock(target)”.

Any other ideas ?

Grüssi

Abra
We need your Help !!!
New to wagic ? Be sure to check the following :

Bug report: Bug reporting
Help us: Add cards & Compiling.
Customize: Themes FAQ, All images thread, Abra's Mediafire folder
wololo
Site Admin
Posts: 3727
Joined: Wed Oct 15, 2008 12:42 am
Location: Japan

Re: Parser - Ideas for addition

Post by wololo »

good points.

To me the most important step we should take with the parser is migrating it to a real parsing mechanism using Lec and Yacc. This is 100% technical, it will bring nothing new, but it has become necessary since the parsing method is now an awful 800 lines (If it were professional software I would be killed for that :p ).
This would lead to a real grammar, structure, etc... less messy than what we have now.

Back on your suggestions:

Triggers
triggers will be coded using the "@" keyword. This is valid for all "at...", "when..." and "whenever..."
for example (this is not necessarily HOW we will do it, but it is an example) @Added(*|stack): to mean: "whenever a spell is played", or @Added(creature|opponentstack) to mean "whenever opponent plays a creature spell" ... you see the idea.
Crude examples:

Ank Of Mishra:
@Added(land|opponentplay): damage:2 opponent
@Added(land|myinplay): damage:2 controller

Crystal Rod:
@Added(*[blue]|stack): may {1}:life:2

Crystal Rod is an example of something super complex to code as it involves a trigger, the "may" keyword, and the need to pay a mana cost. Not sure how easy it will to code, not mentioning the User Interface...

Damage Equal to Power
I've seen a nice suggestion over at the slightlymagic forums (I highly suggest you go there and read the MTGForge forums since they are pretty much doing the same kind of stuff), which would be to use "p" and "t". So it looks a lot like what you were saying.

stuff like:
{t}:Damage:power target(creature)

This would also be a nice opportunity to start handle the "X" costs.
HOWEVER, power/toughness need to be computed when the action resolves (not when we create the C++ object in the parser).
This means the "Damager" class should not take an int as a value, but a different kind of object (a string sounds easy maybe), and the string would need to be parsed in the "Resolve" method.
sound doable.

Other Ideas
One of my current goals is to have more cards in the 10E set than in the RV set. So anything that can improve our coverage of the 10E set sounds cool to me.
On top of my head: Interaction with the library, Damage prevention, Equipment, triggers
gdspsp
Posts: 64
Joined: Thu Oct 16, 2008 3:04 pm
Location: ohio, usa

Re: Parser - Ideas for addition

Post by gdspsp »

hello abra,

if i am understanding correctly, you are asking for suggestions to code in parser??

one thought i have is a search zone function that allows type. for instance many cards have search library, some have you search for specific card type. i know we are able to acquire cards from graveyard; however, this function could be universal for all instances of "card search" (hand, opponent hand, library, opponent library, graveyard, opponent graveyard) furthermore could functions coded in parser be used with search zone (discard, putintoplay, etc)

another thought would be the implementation of "cycling" and even "landcycling", again it seems that the landcycling will require a search zone function. "cycling" by itself could be done semi easy...we have discard, we have draw, we just need the option to choose cycle instead of "casting a spell".

i am sorry for my basic grasp of code language, please let me know if i am off on this subject.

gdspsp
baldersmashed
Posts: 156
Joined: Sat Apr 25, 2009 12:00 am

Re: Parser - Ideas for addition

Post by baldersmashed »

As it was mentioned somewhere else before, the 'foreach' function has the possibility to be able to handle the corrupt ability by simply allowing it to be able to use the draw, life, damage, and other functions that already exists. Maybe I am missing something because I don't code the program, but I have seen this suggested before as well as suggested it myself.
Dr.Solomat wrote:"Vegeta! What does the scouter say about Wagics power level?"

"It's over ten thooooouuuuuusaaaaaaaaand!"

"What 10.000? There's no way that can be right!"
wololo
Site Admin
Posts: 3727
Joined: Wed Oct 15, 2008 12:42 am
Location: Japan

Re: Parser - Ideas for addition

Post by wololo »

baldersmashed wrote:As it was mentioned somewhere else before, the 'foreach' function has the possibility to be able to handle the corrupt ability by simply allowing it to be able to use the draw, life, damage, and other functions that already exists. Maybe I am missing something because I don't code the program, but I have seen this suggested before as well as suggested it myself.
Yes. Lots of things could be done by simply tweaking what already exists. There's a bunch of holes in the parser that could be easy to fill
Onitenshi
Posts: 122
Joined: Sun Apr 12, 2009 12:56 pm
Location: Austria

Re: Parser - Ideas for addition

Post by Onitenshi »

I don't know how difficult it would be to code this, but permanent triggers would be good, for example for cards with "at the beginning of your upkeep" or "at the end of each players turn".
ImageImageImageImageImage
Dr.Solomat
Posts: 975
Joined: Mon Dec 15, 2008 5:12 pm
Location: Germany

Re: Parser - Ideas for addition

Post by Dr.Solomat »

wololo wrote:
Triggers
triggers will be coded using the "@" keyword. This is valid for all "at...", "when..." and "whenever..."
for example (this is not necessarily HOW we will do it, but it is an example) @Added(*|stack): to mean: "whenever a spell is played", or @Added(creature|opponentstack) to mean "whenever opponent plays a creature spell" ... you see the idea.
Crude examples:

Ank Of Mishra:
@Added(land|opponentplay): damage:2 opponent
@Added(land|myinplay): damage:2 controller

Crystal Rod:
@Added(*[blue]|stack): may {1}:life:2

Crystal Rod is an example of something super complex to code as it involves a trigger, the "may" keyword, and the need to pay a mana cost. Not sure how easy it will to code, not mentioning the User Interface...

On top of my head: Interaction with the library, Damage prevention, Equipment, triggers
If you get this to work, we will have a very very much bigger count of playable cards! It would be an explosion!

wololo wrote:Yes. Lots of things could be done by simply tweaking what already exists. There's a bunch of holes in the parser that could be easy to fill
Good idea! Recently cards like Corrupt were added to the svn in hardcoded condition. Give them some soft codable keywords!


But even if it will last some time to get this work, I have to say: Respect! and Thank you all for participating with this great project! ;)
Sets Coded/Released: Legends, Visions, Weatherlight, Tempest, Stronghold, Portal I & III, Urza's Saga BLOCK, Mercadian Masques, Invasion BLOCK, Mirrodin, Ravnica, Guildpact, Conflux, Alara Reborn
abrasax
Posts: 976
Joined: Wed Oct 15, 2008 7:46 am
Location: Switzerland

Re: Parser - Ideas for addition

Post by abrasax »

Hi,

Thanks a lot for all the input. Unfortunately I'm not able to help with LEX/YACC (I've quickly given a look at it and it is not for programmer dummy like me).

I totally agree on the addition for 10E, I already added a lot that I was able to hardcode in the source (you have to try Dreamborn Muse this card is soo much fun to play with… I will prepare a “depletion” deck for the AI for the next release with glimpse the unthinkable and co…). But let’s get back to the brainstorming stuff…

Trigger

How to let the game make the difference between a "when" function that most of the time only target the card, or a whenever function that is targeting all kind of cards meeting the target description ?

Some Example from 10E

Bogardan Firefiend--->When Bogardan Firefiend is put into a graveyard from play, it deals 2 damage to target creature.
@added(graveyard):damage:2 target(creature)
Aven Cloudchaser--> Flying, When Aven Cloudchaser comes into play, destroy target enchantment.
@added(inplay):destroy target(enchantment)

Soul Warden---> Whenever another creature comes into play, you gain 1 life.
@added(creature|inplay):life:1

Maybe one solution would be to add an @each function.

So it would give
Soul Warden---> Whenever another creature comes into play, you gain 1 life.
@each added(creature|inplay):life:1


In fact at the moment, the @ is only for phase of the game. We would need to define the different "trigger" and then to code a trigger for each individual event, that could be

-when put in play
-when put in graveyard
-when damaged
-when blocked or blocking
-when attacking
-when tapped

For the when put in play, instead of “added” which will not be entirely correct (e.g. some cards will state when comes into play from your hand…) I was thinking of a movetofrom kind of keywords

Example from 10E

Megrim--> Whenever an opponent discards a card, Megrim deals 2 damage to that player.
@each movetofrom(opponentGraveyard,OpponentHand):damage:2 controller

Underworld Dreams--> Whenever an opponent draws a card, Underworld Dreams deals 1 damage to him or her.
@each movetofrom(opponentLibrary,oponnentHand):damage:1 controller

Festering Goblin - When Festering Goblin is put into a graveyard from play, target creature gets -1/-1 until end of turn.
@movetofrom(graveyard,inplay):-1/-1 target(creature)

Bogardan Firefiend--->When Bogardan Firefiend is put into a graveyard from play, it deals 2 damage to target creature.
@movetofrom(graveyard,inplay):damage:2 target(creature)

Aven Cloudchaser--> Flying, When Aven Cloudchaser comes into play, destroy target enchantment.
@movetofrom(inplay,*):destroy target(enchantment)

Chromatic Star - {1}, {T}, Sacrifice Chromatic Star: Add one mana of any color to your mana pool. When Chromatic Star is put into a graveyard from play, draw a card.
auto={1}{T}{S}:add {Z}
auto=@movetofrom(graveyard,inplay):draw:1 (this one would probably make the game crash anyway ;) )

Denizen of the Deep - When Denizen of the Deep comes into play, return each other creature you control to its owner's hand.
Auto=@movetofrom(inplay,*):moveto (ownerhand) all (creature|myinplay)

Also for the other one I don’t know what kind of keywords we could use, but we could do something as simple as “tapped”, “attacking”..etc..etc..

Example from 10E

Overgrowth -->Enchant land-->Whenever enchanted land is tapped for mana, its controller adds {G}{G} to his or her mana pool (in addition to the mana the land produces).
@tapped:add {G}{G}

Manabarbs-->Whenever a player taps a land for mana, Manabarbs deals 1 damage to that player.
@each tapped(land|inplay):damage 1 controller

Regarding the cards that have a function at each phase, instead of using the same keywords (I suppose it would be more complicated to code) we could use an @all “phase” e.g. @all upkeep:draw:1.

Example from 10E
Verdant Force - At the beginning of each upkeep, put a 1/1 green Saproling creature token into play under your control.
auto=@all upkeep:token(creature, saproling,1/1,green)


foreach

Also I’ve looked at this one, and spent quite some time trying to figure how it works, and also try in a first step to code a kind of damage foreach function, without success. This one is too complex for me. It would require the genius of wololo, because at the moment foreach is coded as a lord parser type, and also the foreach thing is not a target ability… nevertheless as everybody agree we could add the following:
Foreach(X):damage:Y target(Z)
Foreach(X):discard:Y target(Z)
Foreach(X):life:Y
Foreach(X):draw:Y

Example from 10E
Stronghold Discipline - Each player loses 1 life for each creature he or she controls.
auto=foreach(creature|myinplay):life:-1
auto=foreach(creature|opponentinplay):damage:1

Sudden Impact - Sudden Impact deals damage equal to the number of cards in target player's
auto=foreach(*|opponenthand):damage:1 (not 100% correct but who will target himself?)

damage to power/toughness/X
I will look at this one… I also think it is doable…would be on my personal Totry for the next release…

counters
I was also thinking of adding a kind of “counter” keywords, but my first thought was that it will not be able to really “understand” it is a counter and just add or remove permanently +x/+x, anyway some cards hardcoded are using counter so it this one is on my tolookat list.

Doesntuntap
Leungj also mentioned to me the “doesn’t untap” one… which is brass man or basalt monolith, I’ve try also to look at this one, without success… gatherer has 116 cards with lookalike “doesn’t untap” text (although maybe only 30% could be added with this keyword).. anyway it could also be added.

Example from 10E

Dehydration - Enchant creature (Target a creature as you play this. This card comes into play attached to that creature.) Enchanted creature doesn't untap during its controller's untap step.
Target=creature
auto=doesntuntap

Colossus of Sardia - Trample Colossus of Sardia doesn't untap during your untap step. {9}: Untap Colossus of Sardia. Play this ability only during your upkeep.
auto=doesntuntap
auto={9}:untap

Well this last example could be harcoded too, but it would be nice to have it in the parser.


Others
I’ve also noticed that the moveto all function only work with “inplay” at the moment, making it work with all zone will definitely add some cards.

Also adding a “all” to tap and untap (and also target) could add some cards (untap all has 98 occurrence in gatherer, tap all has 169).

Example from 10E
Deluge - Tap all creatures without flying.
auto=tap all(creature[-flying])


Also last but not least, as we already discussed somewhere with wololo, the cantbeblockedby(X) and cantblock(X)… so I’ve also look at this one, without success at this stage but I did not abandon all hope at the moment…:D

Example from 10E
Elven Riders - Elven Riders can't be blocked except by Walls and/or creatures with flying.
auto=cantbeblockedby(creature[-walls;-flying])

Juggernaut - Juggernaut attacks each turn if able. Juggernaut can't be blocked by Walls.
auto=cantbeblockedby(walls)
auto=mustattack

Also thank for the addition of the search function (huge, great, etc…), equipment would also be great… (gatherer has 85 equipments)


well, enough for today’s thinking, thanks to everybody..

Grü

Abra.
We need your Help !!!
New to wagic ? Be sure to check the following :

Bug report: Bug reporting
Help us: Add cards & Compiling.
Customize: Themes FAQ, All images thread, Abra's Mediafire folder
abrasax
Posts: 976
Joined: Wed Oct 15, 2008 7:46 am
Location: Switzerland

Re: Parser - Ideas for addition

Post by abrasax »

Hi,

Also just to report some progress.

I just added a few minutes ago "cannotbeblockedby", seems to work but need to be tested a little more.

"Doesnotuntap" as also be added (as abilities=) but it seems to be a little buggy, I inspired myself from brass man and co. but this card are not 100% correct since you can activate abilities at any moment (should only be during your upkeep). Also it does not work with enchantment so I hardcoded also dehydratation (10E) but unfortunately at this time it "untap" the creature you are enchanting when you cast the enchantment...
Also We need to wait before adding some other cards with this ability.

I also added "tap all" in the parser you can now use this one... I could also add "untap all" but I will wait since again the whole untap function seems to be a little buggy.

I tryed to add a "foreach(target) damage:X" without success, I give-up on this one... the foreach function as been coded as a Lord in the parser and I'm not sure I could add anything to it... wololo could have a look at it... But I'm not sure it will add so much card... I already "hardcode" all the one I could come accross in the official set...So It's not on my todo list anymore

On my todo list ATM:
- Adding damage:power to the damage function in the parser.
- Adding "counter" to the parser.

As alway any Ideas are welcome, but please try to take some "concrete" example from set, and also try to make some research to have an overview of "how many" cards could be added.

Grüssi

Abra
We need your Help !!!
New to wagic ? Be sure to check the following :

Bug report: Bug reporting
Help us: Add cards & Compiling.
Customize: Themes FAQ, All images thread, Abra's Mediafire folder
wololo
Site Admin
Posts: 3727
Joined: Wed Oct 15, 2008 12:42 am
Location: Japan

Re: Parser - Ideas for addition

Post by wololo »

Thanks abra.
"untap all" should not be an issue.
I wasn't clear. The "untap" code works alright, it's the "prevent untap" code (for example in Brass man and paralysis) that is bugged.

Regarding "damage:power", "damage:X", etc...: we need to update the "Damager" abilities so that they take not an int as their source of damage, but a more flexible object such as a string, or even a new class. I'll try to work on that soon to show you what I have in mind.
Post Reply