Games, programming, and Magic: the Gathering. What more could you want?

Archive for the ‘Programming’ Category

Redesigning for Fun and Profit

Well, I’m sorry to say that the current version of Crystal Lotus (for Windows Forms) is going away. I will spend a blog article or two discussing the code, but essentially the main progress I made was with the deck editor and core card functionality. The majority of my time was spent being frustrated with NeoForce Controls, XNA 3.1, and .NET 3.5 before I finally switched to Windows Forms. The code was all ported successfully, but the project stalled not long after due to school-related workloads.

Thankfully, I’m switching to EnigmaEngine, XNA 4.0 and .NET 4.0 for a fresh start. I’ve also talked and read more about designing and writing a rules-enforcing application, so I feel better prepared. I will do an entre-mortem of Crystal Lotus 0 (I’m a programmer… I count starting from 0). Then, after my tests in May, I’ll jump start Crystal Lotus.

Before I begin my entre-mortem, I would like to mention that I’m a high school student. As a result, I haven’t taken an actual CS course at a college or university, but I have been programming C# for well over 2 years. Therefore, kindly judge by quality of code or end product rather than age or the fact that my life is hectic with AP and IB tests and classes.


Generally, in the games industry, a development team will conduct and publish a post-mortem of their game several months after the first or second patch of their game. However, since Crystal Lotus is nowhere near finished and is instead adopting a ‘one step sideways’ plan of action, an entre-mortem seems more appropriate. An entre-mortem is simply a reflection on the design and development of the application. For Crystal Lotus, the entre-mortem will focus on the code and code design but will stray into art and UI occasionally. Additionally, the optimistic scope of the project will be discussed, with the intent about reaching a reasonable conclusion about the development timeline for such audacious projects. (more…)

Wishful Thinking

Well, I did the Global Game Jam this weekend (solo!) and didn’t quite manage a game to the extent that I wanted. It started off pretty awesome, but I ended up adding actual gameplay (simple enemy logic and a survival mechanic) in order to end up with a game rather than a tech demo. I did this in the last hour before submission, so it was essentially an alpha version. Not bad for 20 hours, though.
How does this relate to Crystal Lotus? Well, much of the engine that I developed for this RPG is easily reusable, and the data-driven format makes it even better. I started experimenting with Perlin Noise algorithms to generate terrain as well, meaning that it’s possible to create an extensible world. Additionally, Perlin Noise algorithms could be used to determine AI traits/features in a manner better than mere random numbers – related traits would located nearby each other on the generated texture, allowing for a certain amount of dependency and randomness without hardcoding it in.

Omniscient Onions

Well, thankfully, all-knowing leeks don’t exist.
But guess what onions have? That’s right – layers! And guess what cards have – layers! But by corollary, aren’t cards omniscient? Technically, no… but yes.

Leaving aside my CardLayer mention, each card has to know about every other card’s state, as well the condition/life totals of players, library, graveyard, exile, and so on. You could say each card has to know the GameState. But since a GameState can change quickly, the GameState is rather one of many GameStates – there is a GameState for each potential future action you could do, such as drawing a card, casting a spell, attacking, or activating a creature’s ability. Essentially, this means that the GameState has to be easily copied and modified, especially so that the AI can use it to predict the results of casting a card or declaring a certain creature as a blocker.

Interesting, right? But not relevant to our knowledgeable vegetables and their thrice-accursed layers! Well, think back to the comprehensive rules… and remember the card Diminish. And its mother, Godhead of Awe. What these two little cards do is override a creature’s power and toughness, making it a 1/1.
But what of Lignify? Well, beyond P/T changing effects, Lignify also deprives creatures of abilities, such as haste or morph.
Now, let’s kick it up a notch. What happens when Lignify enchants a creature – say, Prodigal Pyromancer – and then you cast Godhead of Awe? Well, Pinging Timmy there is a 1/1 just like always… but can’t ping. And it’s all thanks to the magic (pun intended) of layers.
Now, why does this matter for programmers? We can always hack it in! But, really, creating a CardLayer class that does such things as allowing for replacement or modification of stats is VITAL. It makes your code cleaner, easier to read/write, and more compliant with the comprehensive rules.
So, over the past couple of days, I’ve been coding that class.
Each of those accessors – the brunt of the class interface – are two-way get/set, meaning that they are used to both access and modify the layer’s attributes. Aside from that, a simply “Copy” method and a additive operator do the grunt work of the class. The additive operator makes code easy when stacking multiple layered effects, and the Copy operator allows for a card like Lignify to internally store a CardLayer and simple copy it onto each creature it enchants.

Deep breath! You’re done with the article now! Comments, criticism, etc?

Turkeys, Code and Cards

Well, today’s blog entry is all programmer content. Huzzah!

The deck editor, as you’ll recall, has a search function on it that lets you use card names, costs, colors, types, rules text and creator information to find the exact card you were thinking of. With each press of the “Go” button the list of cards grows progressively shorter until you press the “Clear” button. Simple enough, right?

Actually, it was fairly easy. It turns out that since I plan to let users search through any part of a card’s text, I don’t need to implement any algorithms like ShellSort. Instead, I used RegEx – regular expressions – and checked for matches with the pertinent info. However, since MtGColor is an enumeration, I preformed a brute-force query on it to allow the user to search through colors.

The chief other feature differentiating my deck editor from those in Forge or Wagic is the format enforcement. Formats are completely data-driven, so you can go ahead and create your own custom format or block format as you wish. Checking if a deck is format-legal is also rather simple. First, I ensure that the maindeck and sideboard meet the format’s criterion, and then I go through each card in the deck and ensure that it fits within that cards format limit – e.g., banned and restricted cards are supported as easily as Relentless Rats and basic lands.

One minor quirk in my Deck Editor is that the images for cards are downloaded off the internet and then cached onto the hard drive, but it uses the same thread as the actual deck editor GUI. This pause is generally unnoticeable on my laptop, but on occasion takes as long as a second and a half. I did go in and tweak my code to multithread image downloading, but it caused a handful of other bugs. So, unfortunately, you’ll have to bear with a pause or two when first viewing cards.

The final item of note is that I’ve begun working on the rules-enforcement code. I haven’t added in a scripting engine yet; I’m considering Lua at the moment. I also haven’t implemented a GUI, but have plans to develop one in WPF. On a side note, since I’m a Rules Advisor (having passed the test), I’m hoping to make my engine 100% rules compliant for cards after 4th edition (that means no ante or such… or Shahrazad! – which, BTW, means “luck” or “fate” in Hindi). Technically, I should reread the comprehensive rules day by day as I code my engine, but no one has that much time! However, I’ve had a breakthrough about how to code cards that no other engine whose source code I’ve read has effected.

But I’ll be back Sunday night to post about that!

Tag Cloud