tag:blogger.com,1999:blog-64251896757634787772024-03-13T11:19:52.447-07:00The SharpeningHellfishhttp://www.blogger.com/profile/16234004537393923817noreply@blogger.comBlogger12125tag:blogger.com,1999:blog-6425189675763478777.post-13681883202215316662011-10-30T03:11:00.000-07:002011-10-30T03:15:09.056-07:00Cards!Gamemat!Action!So the Action-mockup is taking shape, it only took several weeks. >:/<div>The better news is that there is apparently some merit to the model because it is similar to what silly freak (Laterna Magica, link in the sidebar) is doing, only less advanced as he is generating his abilities straight from parsed Oracle text. Go check it out!</div>Hellfishhttp://www.blogger.com/profile/16234004537393923817noreply@blogger.com0tag:blogger.com,1999:blog-6425189675763478777.post-21546653619950993922011-09-04T10:12:00.000-07:002011-09-04T10:32:51.844-07:00Round ReinventionIf a change is major enough at this stage of a project, I sometimes just knuckle down to reboot the entire thing to have an easier time incorporating the change. Looking at my projects folder, Sharpening has undergone 4 of those reboots.Unless I am misremembering, the first time was when I added the provisions for text-altering spells (Artificial Evolution and the like), the second time was when Activatables took off, and the latest time(a week or so ago) was when I discovered that I was actually reinventing the wheel by rolling my own "Treat C# as scripts" solution for the cards.<div>I now make use of the excellent CSScript library, which eliminates roughly a third of my own experimental, buggy code to load,compile and sandbox the scripts.The only downside versus my solution is that I haven't found a way in CSScript to specify multiple scripts to be compiled into one assembly but that is not a major downside, as all scripts will be sandboxed the same way and I can instantiate objects from the assemblies as I go.It's also not really the domain of CSScript, so meh.</div>Hellfishhttp://www.blogger.com/profile/16234004537393923817noreply@blogger.com0tag:blogger.com,1999:blog-6425189675763478777.post-81500545604448598632011-05-23T14:34:00.000-07:002011-05-23T14:51:22.846-07:00Write the program for meMan, this place is dusty. Time to put it to sporadic use again!<div><br /></div><div>The title refers to scripting, I'm not gonna hand over the reins to anybody! :P</div><div>Basically what I have in mind (and have gotten seemingly working great) is that cards and "Actions"(the concept of which is a WIP) is a hybrid between hardocding and scripting in that you write the cards as full-fledged C# ( I could potentially allow other .NET languages down the line) classes that inherit from a base class and you can reference and use any code exposed by a project called "Sharpening_Exposed" (How witty) . However, the card files aren't compiled together with the actual program but only when (for "Actions") the program loads or (for "Cards") when they are used in a deck. This lets you have both the code flexibility of hardcoded cards and the plug-and-play-ity of scripts.</div><div><br /></div><div>There are some safety concerns, of course, like "What's stopping a card code from accessing the filesystem and network to steal data in a maliciously tampered distribution?". I'll tell you what: A whole lot of AppDomain voodoo that's been my headache for a while. >_> Basically, an AppDomain is an isolated area of code that operates with certain permissions. Fully trusted code can do anything, but I've taken away all permissions except code execution from the AppDomain that will run the compiled cards and "Actions" so all that happens if they try something like that is a SecurityException will be thrown.</div><div><br /></div><div>Mind you, that's a *very* brief overview. ;)</div>Hellfishhttp://www.blogger.com/profile/16234004537393923817noreply@blogger.com4tag:blogger.com,1999:blog-6425189675763478777.post-3918682923065958262011-01-09T05:46:00.000-08:002011-01-09T05:48:21.758-08:00Offline ExperimentationSharpening is currently undergoing some offline experimentation with some abstractions ( to be even vaguer, they apply to what can be done ;P ), hence no activity on the SVN. It may not show on the blog, but I'm having the time of my life with this project ^^Hellfishhttp://www.blogger.com/profile/16234004537393923817noreply@blogger.com0tag:blogger.com,1999:blog-6425189675763478777.post-91566113491770852742010-11-30T11:58:00.000-08:002010-11-30T12:10:17.641-08:00Utopia: Crushed<blockquote></blockquote>Not dead. Dreaming.<div><br /></div><div>So, seemingly just to spite my pledge, it turns out that even if you somehow implement every rule of Magic perfectly, with every obscure corner case handled, there must always be card-specific code. That is because there is a card that basically has card-specific rules, the comprules.doc equivalent of card-specific code.I'm talking about <a href="http://gatherer.wizards.com/Pages/Card/Details.aspx?multiverseid=201224">Rasputin Dreamweaver</a>. I'm pretty sure it is the only card in MtG history to make use of the state based action:</div><div><blockquote></blockquote><blockquote>704.5s If a permanent with an ability that says it can’t have more than N counters of a certain kind on it has more than N counters of that kind on it, all but N of those counters are removed from it.</blockquote></div><div>So an MTG-implementation can't yet be truly without card-specific code because MtG itself has basically card-specific rules.</div><div>And before you point out <a href="http://gatherer.wizards.com/Pages/Card/Details.aspx?multiverseid=980">Shahrazad</a> as another card that is alone in the use of a rule, let me be nitpicky and point out <a href="http://gatherer.wizards.com/Pages/Card/Details.aspx?multiverseid=74312">Enter the Dungeon</a>.</div><div>Just a curious thought.</div>Hellfishhttp://www.blogger.com/profile/16234004537393923817noreply@blogger.com0tag:blogger.com,1999:blog-6425189675763478777.post-35557357250474634102010-10-01T00:37:00.000-07:002010-10-01T01:26:20.677-07:00*Hellfish casts Rise From The Grave targeting blog*Because of a job-issue (the lack of any), things have been quiet for a while. I refuse to let this turn into an emo whinepost about it, though, this is a programming blog, damnitall! Just know that I have uncommitted code working further towards modifiable costs as well as the beginnings of a UI outline.Hellfishhttp://www.blogger.com/profile/16234004537393923817noreply@blogger.com0tag:blogger.com,1999:blog-6425189675763478777.post-17311381199299160972010-08-23T10:19:00.000-07:002010-08-23T10:22:52.459-07:00Quick Attack!Just a quick post to update y'all on what's going on: I'm ripping out the InputStateMachine code into a separate project for testing and ironing out design issues. Also, I'll take the opportunity to test out the UIBridge.<div><br /></div><div>Though that DS sure is tempting... Damn Pokemon Pearl! Havn't been this addicted since Blue!</div>Hellfishhttp://www.blogger.com/profile/16234004537393923817noreply@blogger.com0tag:blogger.com,1999:blog-6425189675763478777.post-67480295214479882462010-08-10T00:39:00.000-07:002010-08-10T04:02:59.216-07:00In which you'll get an opportunity to point and laugh at ugly ugly codeSo I've implemented a first stage prototype (I love using those words) of the "Dependency Walker" continuous effects sorter, the basics of which I went through in the last post. So now the process will be something like:<br /><br />Card tells the engine it wants to supply a continuous effect, and supplies the different parts of the effect in addition to what the entire effect(or parts of it) depends on (such as "Targets type" for Gaia's Anthem) as well as which layer each part goes in. The engine sorts those layers first by CDA-nonCDA,then by Dependency using this code below and then by timestamp (also below).<br /><a href="http://sharpening.pastebin.com/5PSCpt4U">http://sharpening.pastebin.com/5PSCpt4U</a><br /><br />NOTE: That I still think I have some corner cases to handle, but the principle will be the same.<br />EDIT: Of course, there's also the rather BIG corner case (:P) of having no circular dependency, in which case the walker shouldn't be used at all. Fixed.Hellfishhttp://www.blogger.com/profile/16234004537393923817noreply@blogger.com0tag:blogger.com,1999:blog-6425189675763478777.post-78956176642938094782010-08-04T01:29:00.000-07:002010-08-04T02:02:58.623-07:00The roots kiss the sky and the crown bites the dustI bet alot of you who read my second entry on this blog chuckled quietly to yourself. "Oh, he'll feel the pain of actually trying to *implement* a continuous effects system with dependencies soon enough." :P Well, if you did, you were right. Dependencies are beating me up, though I have made some headway. The tracking of their dependency wasn't the problem, that works in theory (everytime I say something works, you should probably add "in theory" because until I start prototyping cards I can't actually test anything),the problem is of course comparing the dependencies/targets and sorting accordingly.<br /><br />In addition, I must be able to weed out circular dependencies and apply those effects in timestamp order instead. The idea I have so far is:<br /><ol><li>Determine all dependencies for all effects. That is for each effect E: Loop through each other effect F and if that F's target field is in E's list of dependent fields, add E to F's list of dependants and F to E's list of dependsOn. To represent this visually, it kind of becomes an "upside-down tree structure" (Damn language difficulties).</li><li>While there is an effect E with an empty dependsOn list, add E to the final list of Effects for the layer.</li><li>(This is the part I'm wrestling with currently.What we have left is a bunch of effects that all depend on one or more of the other effects.) What I'm pondering is designing a sort of recursive function "tree walker" that will traverse the tree and mark each effect it passes as visited and branch for each effect the current effect dependsOn and if a branch returns to a previously visited effect before reaching a leaf(an effect that no other effects dependOn), all the effects it visited will be part of a dependency loop and should be added to the final list of Effects in timestamp order.</li><li>If there are still effects remaining, go to step 2.</li></ol><p>This sorting WILL be expensive but probably has to be done everytime a continous effect is added/removed.</p><p>Thank Urza I have other things to do to clear my head! Costs are now mutable and Activatables have been restructured to further simplify "cast without paying". Now you cannot create your own Activatables anymore, you have to go through the ActivatableFactory and get a "Base Activatable" that only handles the cost payment(s). Then, you append the desired effect to the base activatable. The reason is that this way I can depend on payment being the first effect listed and as such, skip it everytime cast-without-pay is needed. Now to figure out how conditional cast-without-pay will be handled there. (Traps).</p>Hellfishhttp://www.blogger.com/profile/16234004537393923817noreply@blogger.com0tag:blogger.com,1999:blog-6425189675763478777.post-78280619115031549822010-07-26T01:31:00.000-07:002010-07-26T02:56:07.614-07:00ActivatablesIf not for Activatables, cards in Sharpening would be very useless, unless you turn it into some sort of collector's simulator. So what are activatables? A lot of things.<br /><ol><li>They are the activated abilities of permanents.</li><li>They are the act of casting any spell.</li><li>They are any alternate way of casting any spell. (Flashback,Buyback,Cycling,Ninjutsu,"You may X instead of paying this card's casting cost")</li></ol><p>Basically, they're everything you can do with a card beyond holding it in your hand.Activatables contain:</p><ul><li>A Condition, "CanBeActivated"</li><li>A CompoundEffect, "ActivatedEffect"</li><li>A CompoundCost</li><li>A CardBase, "CardSource"</li><li>A string, "Description"</li><li>Tags for wether the Activatable is a mana ability or a regular ability.</li></ul><p>The plan is that when you click on a card in the GUI side of things, the UI raises an event in it's bridge to the Sharpening core (More on the bridge in a future entry) and the library will round up all the Activatables of the clicked card and ask them if they could be used at the moment. For this, each Activatables "CanBeActivated" checks whatever is needed. For instance, Flashback "CanBeActivated"s checks that the card is in the graveyard and returns true if so.Then, the library will make a call back in to the GUI to present the player with a choice of the Activatables that were usable (unless of course there was only one, then that will be run). Then, the chosen or lone Activatable's CompoundEffect(One or more effects) "ActivatedEffect" is run. The effect will often, but not always, start by setting the InputStateMachine to "Pay Cost" mode so that it's CompoundCost(One or more Costs, of any type) can be paid one by one. Then, the Effect will do whatever it specifically should. Continuing with the Flashback example, this would be "Do the same as the hardcasting Activatables Effect, AND then exile the card.". </p><p>To simplify card creation, I provide two Factory classes that the cards can use to create Costs(not just mana costs) or full-on Activatables. For example, to add Flashback to a card, you could simply use a statement like</p><blockquote>this.activatables.Add(ActivatableFactory.Create(this,"Flashback:2 U<br />U,Discard(1,Any)"));</blockquote><p>and the ActivatableFactory would create the two costs for you (using the CostFactory), insert the proper CanBeActivated condition and copy the hardcasting directly from the card(with the added Exile effect).</p><p>If at anytime a card would require an activatable that the ActivatableFactory can't create(not a rare situation), a custom Activatable can be written directly in the cards code using anonymous delegates for the Condition and Effects. I am also thinking about letting the ActivatableFactory create a BaseActivatable that only takes care of paying the costs and let the card writer tack on the actual effect at the end. Otherwise, you'd have to write boilerplate cost-paying code everytime you write a custom Activatable.</p><p>Oh crap, I'm starting to ramble. Well, that's Activatables.If something doesn't make sense, it could be either that I muddled it up or because it depends on something else that I havn't touched on yet. In closing, I want to make a pledge.</p><p>"I'd swear on my mother's grave, were she not alive and well, that I will never, EVER, place card-specific code in the core of Sharpening, so help me Niv-Mizzet." Amen.</p>Hellfishhttp://www.blogger.com/profile/16234004537393923817noreply@blogger.com2tag:blogger.com,1999:blog-6425189675763478777.post-13737192683979710962010-07-23T05:40:00.001-07:002010-07-23T05:55:11.535-07:00Continuous Dependencies<blockquote></blockquote><blockquote></blockquote>Just a quick post today, since I've only just gotten home late last night and am settling back in.<div><br /></div><div>However, this is not really an issue that will be tackled quickly. I will describe the idea I had for dependencies in the layer system,though.</div><div><br /></div><blockquote>613.7a An effect is said to “depend on” another if (a) it’s applied in the same layer (and, if applicable, sublayer) as the other effect (see rules 613.1 and 613.3); (b) applying the other would change the text or the existence of the first effect, what it applies to, or what it does to any of the things it applies to; and (c) neither effect is from a characteristic-defining ability. Otherwise, the effect is considered to be independent of the other effect.</blockquote>The idea I had is that, in C# (and other languages on the .NET platform) you can use techniques known as "Reflection" to access to structure of the various objects your program. I will use reflection to obtain, for each entry into the layer system, information about which of the characteristics(Members of the card object, or possibly the card objects CharacteristicCollection object) that entry depends on and what values it depends on these characteristics being.(Sentence trainwreck, woo) as well as what characteristics it changes. This way, I have all the data I need to sort after first CDA(Characteristic Defining Ability)/non-CDA, then dependency, then timestamp in each layer before running the effects of the layers.<div></div>Hellfishhttp://www.blogger.com/profile/16234004537393923817noreply@blogger.com0tag:blogger.com,1999:blog-6425189675763478777.post-61059597790959054102010-07-18T04:54:00.000-07:002010-07-18T05:58:44.371-07:00The Sharpening (or YAMTGREE)So yeah, I'm programming a MTG rule enforcement engine.Again. Last time was a mess, and alot of that was because A) I didn't actually *know* about the comprehensive rules document and B) the magic I had played the most was in the form of Shandalar. That's what? Fourth or fifth edition? Now I feel like that is less of an issue with a lot of Forge,MagicWars,Botarena and even cardboard time logged and a kneejerk reaction to open up comprules.doc every time the AI does something suspicious.<br /><br /><span style="font-weight: bold;">So what's this program all about?</span><br />Glad you asked.It was born from a coding spurt combining with some random floating thoughts about implementing text-changing effects in Forge. It takes the shape of a C# class library and not a full program, because I will probably end up making a basic UI with WinForms, which will probably not be portable. This way, any .NET UI can be made and hooked into the library.<br />The card format that will be used is a little odd. It's sort of halfway between scripted and hardcoded in that the cards aren't compiled until the decks used by each player is loaded, but they are written as full-on C# classes in source files. With the help of some reflection and run-time compilation shenanigans, card classes (inheriting from a CardBase) will have access to all of the various facilities of the engine, such as the Input State Machine(inspired by Forge's), the Activatables (Which basically define everything that a player can do with a card, from hardcasting to activating abilities), the Scheduler (For effects with durations) and a hopefully correct Continuous Effects Layering System(Oh, the important horror!).<br /><br /><span style="font-weight: bold;">Open source?<br /></span>Eventually. Like any new project of mine, it's ugly. Hideous, in fact. Until I clean it up and document it, it will remain closed source. The cards, however, are fine to read and use as example/base of another card once it get's to that point.<br /><br /><span style="font-weight: bold;">What's done/missing?<br /></span>Done:<br />A lot of things are partially done, but that's how it is. Certain things require parts of other things that in turn do the same.That said, I don' think the Scheduler,Priority or Phase mechanics needs more work.<span style="font-weight: bold;"><br /></span>Missing:<br />The Input State Machine needs tinkering with in order to correctly pass data between the user and the library. Something important is also missing: Spell facilities.No stack,no nothing.<br />It is very possible that I've gone about this project in an awkward/wrong way, as I do, because while I already have facilities for Text-changing effects already in place, spells are not supported as I mentioned.<span style="font-weight: bold;"><br /><br />Release?<br /></span>I have 5 criteria for when I will make a first alpha release of Sharpening: A basic UI, of course, Basic Lands implemented and working fine, a creature working fine, a continuous effect working fine and an instant working fine. If you follow this blog, you'll know when any of this happens. ;)<span style="font-weight: bold;"><br /><br />Next?<br /></span>More Input State Machine tinkering, and beginning the Spell framework.I hope this'll keep your attention (and mine xD ) for a while longer!<br /><br />Oh god, when I finished writing this I reflexively reached for the "Build Solution" shortcut key.. I've been programming too much already.Hellfishhttp://www.blogger.com/profile/16234004537393923817noreply@blogger.com4