Password:
Remember me:

 


Thursday, September 30th, 2010
4:40 PM
Quite possibly the most annoying part of typing up a lengthy post is accidentally clicking away from the page or closing the browser and losing all of your text. No more will that be an issue with a new feature being added to the NilsBlogPress suite (i really need to get a better name for when I am referring to this thing). Sadly that feature will NOT be autosave, let me explain..

The task sounded easy enough, create some sort of javascript function that would repeat every 30 seconds or so. This function would need to grab the current data inside the textarea used for writing post content, and some how save it to the database in a special autosave table. I immediately turned to AJAX (Asynchronous Javascript And Xml), as an asynchronous call to some other PHP script to do the work of backing up the data to the database would be low impact and let me do things behind the scenes without interrupting the post creation process.

Step one, dust off the AJAX tutorial code I had laying around after doing the W3Schools tutorials, and modify it to suit my needs. The tutorial was for a "hint-box" that would offer a suggestion as you typed a name into an input field:


This was the main triggering function, the input field on the page in question would trigger the function by onkeyup="showHint(document.getElem...)" passing in the text field data, and then send the data to "gethint.php" for processing. GetXmlHttpObject() is also called out in this sample to set up the AJAX calling variable (For source code for those 2 bolded bits mentioned above, check out the W3Schools AJAX tutorials).

So there were some issues with the sample AJAX code.
  1. I need to trigger the code with on a set interval of time.
  2. I don't want this interacting with my textbox at all, just backing it up behind the scenes
  3. The data I wanted to back up would be full of html markup from the rich text editor, I did not trust passing that through GET as I am pretty sure there would be a lot of illegal characters in that URL (GET is a way of passing data that basically puts your variables in the URL of a web page, ie: http://mypage.com/index.php?variable1=value1&variable2=value2)
  4. The PHP worker script would need be changed to collect the data from $_POST and insert it into a MySql database, and then output the last autosave time.

So for starters, I change what was a trigger in the <input> field to be a trigger on load. I had to put this in the header.php of my website as that is where I define <body>, so I added a little if statement to ensure this was only happening on the page where I am working on posts, post.php.


Now I have a function I call immediately when I load up a post creation / edit page. To get the code to repeatedly trigger the asyncronous sending of data I define init() as follows:


That will call the function AutoSave() every five seconds, and that is where I will define my AJAX data send. I hardcode the grabbing of the contents of "textarea1" as that is the only text box I will ever be worried about autosaving.


The setRequestHeader calls at the end of AutoSave() are the method used to pack up my variable, params, into the $_POST data stream. I then call xmlHttp.send with the params var, rather then null, to finalize sending of the data via POST.

Despite my avoiding passing data by GET for fear of unhandled special characters, there are still some characters that confuse the POST data. any & or + symbols would get interpreted as part of the variable defining escape characters. (meaning it looks for & to define additional variables). I also had some trouble with output of "<" characters when debugging to see if i was fetching the data correctly. So to solve these special character issues I added a few lines of string replacement to encode my sensitive characters to something I could easily string replace from the side of autosave.php to decode back to normal.


With all the data collection now handled, I just needed to make sure I was collecting the data correctly from the autosave.php side before I start trying to insert anything into the database.


I also added an output area to post.php at the top left of the RichTextEditor textbox, that would display the last update time, and while debugging would should the data collected.


Now the testing began. First I turned off the Richtext editor as it does strange things with textarea1, turning it in to an <iframe> of sorts, I wasn't sure how that would interact with me constantly fetching the textarea1 contents. Secondly I turned off populating the textarea with contents of the database in the case of editing an existing post, I though that setting the contents of textarea on page load might have some negative impact on trying to fetch the contents later.

With both of these turned off, the autosave works beautifully. I type in some text, it automatically gets captured and appears in my little debug area exactly as I typed it. This looks good, if things keep up I can write some simple SQL and backup logic and be done with this thing. Sadly this is when problems began to arise. While everything was looking fine in IE, in Firefox, every time the ajaxReply area was populated with the "Last autosave compeleted @" string, the whole window would flicker, and the textarea would lose focus and regain focus, setting the cursor to the end of the window. Very bad for a low-impact autosave, the last thing I want is to interrupt a user while they are mid sentence. I did find a solution although it was one I didn't like. As long as I didn't updated the "ajaxReply" area, the page would not flicker and focus would not get lost. I figured giving up my little "last autosave" status message would be ok if it would get it to work.


Farewell my beautiful prompt :'(


The next thing I noticed was that if I turn the database value back on, so I can now see the exisiting content when editing a post, the data I collect in Firefox for backup is ALWAYS the default data. Regardless of what I do to the textarea, even deleting all the contents. For some reason I could not understand,
document.getElementById("textarea1").value; always returns the value the textarea starts with on load. I tried various solutions the internet suggested like document.reset() or document.clear(), but Firefox didn't recognize any of these.

All hope wasn't crushed yet however, I still had IE working. So now I turned the Richtext editor scripts back on. Sadly this stopped everything. I did not write the Richtext editor scripts myself but I do have a pretty good understanding of it. It does some sort of replacement effect on the textarea turning it almost in to an <iframe>. This would seem to kill any hope I had of fetching the data from the textarea however.

With that, I decided to scrap the idea. I learned a lot from the experiment, and maybe one day I will revisit it. I did get a sound piece of advice from a colleague however. If all I was worried about was leaving the post page while in the middle of typing, why not simply implement a prompt that asks "Are you sure you want to leave this page"?



This solution was perfect, and in my eagerness to do a lot of fancy work saving the data behind the scenes, I totally over looked it as a possibility. Coding it up proved rather simple:


With a little bit of code in header.php and post.php, I was able to define a toggle-able prompt that would pop up any time you try to navigate away from the page, close the tab the page is in, or even close the browser. The only thing that would cause people to unwillingly lose data now would be power loss, and that I am okay with =P

It was a long fight and despite not succeeding with my original plan, I learned a lot, and added a new feature to the NilsBlogPress suite. Hopefully for those of you that have read this far, you have learned something too.




Friday, September 24th, 2010
11:00 AM
As I have mentioned in a previous post, I am currently working on a large project to create a Magic The Gathering RPG stylized game. This idea is not at all unique. Magic the Gathering is a well established game, and there have even been RPG magic games in the past. The main one I draw inspiration from is an old Microprose Studios game called "Conquerors of Shandalar":

   

This game was great. It had a randomly generated overworld map, different towns to purchase cards and get quests, random monster spawns (like the Enchantress above) who would chase after you and challenge you to a duel for Ante (meaning cards from your deck are at stake), and a full fledged
AI for in game play.

The draw backs where a large number of bugs, some faulty AI, a sometimes confusing interface, a VERY limited selection of sets available for play, a lackluster story, and no support beyond Windows 98. It is a great sandbox game for wandering around and fighting guys, and they did manage to fit the story in to the Canon of the Magic (right after the Ice Age), but it needs some reworking. This is the inspiration for me to create something new and better then this original. Partially because I want to play a game like this again, and part just to see if I can do it.

So beginning the project, the first step was to plan. First and foremost I wanted to be able to play Magic the Gathering, so I planned out what I would need to learn how to do, and what types of programs/functions I would need in place, to be able to get there. I called these my Piece-wise Programs:


Piece-wise Programs
  1. I needed a Database to store all the card information and images, the structure of the database needed to be easily query-able.
  2. I would need to figure out how to query a database in C# in various ways and read in data from across relational tables and display the output.
  3. I would need to create a decklist file type, and find a way to read it in to C#, and translate it in to a queries for the database, and load the cards of the respective decklist.
  4. I would then need to take card data and load it in to an in memory data structure, to then be passed around through multiple in game "zone" datastructures through an interface. These zones simulating the different areas of play.
  5. Taking a slightly different direction, I then need to figure out how to load images into objects in C# that i can manipulate with the mouse (ie. move around a play area, tap, and untap). Also adding and removing cards from the play area.
  6. Next, I figured out how to compile a composite card consisting of it's original image, and overlayed text boxes to update with the most recently Errata'd text in the Oracle.
  7. A very important tool to create would be one to parse all the information and images from the Gatherer web page and populate the Database file.
  8. And the final piece-wise program I have built to date is the QueryBuilder, now called the Deck Builder. Which takes in variable amounts of specific information, turns it into a query and outputs all results. Then has features for saving cards to a decklist, and or loading a decklist.

This is as far as I have gotten, but there are still plans for future piece-wise programs

  1. Create Manapool management tool that triggers adding to the mana pool on Land-double click and can be drawn from on card double click (assumably from a "hand" zone).
  2. Create an activate ability menu for double click on card
  3. Create a rules parser that will identify rules functionality of cards
  4. Create base rules functions like DealDamge(int amt, TargetObject o), or DrawCards(targetObject From), etc.. Try and create a dynamic rules engine that works like the Card game Flux
  5. more to come...
So with that plan set out, I will keep hammering away until I have something useful. For documentation sake I am going to post each Piece-wise Program here, source code and all and give a description of how it works, what it does, and what I learned from it.



Wednesday, September 22nd, 2010
3:00 PM
For the past two years, I have been frequenting Magic the Gathering sealed/draft tournaments. Wizards of The Coast has set in place a Monthly Player Rewards program that earns players free textless cards and oversized promocards based on the number of sanctioned events they attend. This week I finally got my first MPR cards! The MPR cards are textless cards. When you recieve rewards cards you will get the month's MPR card (DoomBlade) as well as a random MPR card from past a month (Terminate).

   

If there is a set coming out soon you can get an Oversized promo card. Since Scars of Mirrodin prerelease/release is next week, I got an oversized WurmCoil Engine.



Also since this was my first time receiving player rewards cards I also got a shiny new DCI card. Very handy considering I lost my other DCI card and only had my number in the form of a contact on my phone =P. Now if only I could remember my VERY first DCI number as to merge my older records with this current DCI number.


you can't see it but my DCI # is on there



Tuesday, September 21st, 2010
2:57 PM
Low and behold I discovered a nice little program suite called Microsoft Expression Encoder 4. I was able to download the entire suite through work, but I believe there is a trial version on their page. It has a load of features, far beyond what I was looking for, but all of which look like something I'd want to dig in to later. The best part is the easy to use Screen Capture. With one click I can start recording my actions on screen, save them, and encode them to .wmv for easy distribution.


This compact little toolbar is what opens up when you open the Screen Capture

The Screen Capture works simply enough, just click record, specify an area to capture, click record again, and action. With bindable hotkeys default set to Ctrl+Shift+F11 to start/pause, Ctrl+Shift+F12 to stop, and Ctrl+Shift+F9 to zoom, controlling the capture is easy. You can also specify options like "hide the mouse pointer", or select an audio source to capture along with the track (microphone, speakers, etc.).


Best of all though, I look like a super pro employee : )

I will have to revisit this program in the future and try out some of the other nice features. For now I will likely just use it for presentation recordings at work, and maybe even put up some tutorial videos on this blog.




Friday, September 10th, 2010
2:26 PM
A little over a year and a half ago I started work on a very ambitious project. And while I haven't gotten far towards the end goal, I have made some pretty successful achievements and learned a lot. The project I am talking about is a Magic the Gathering PC game that would bring together:
Holy hell, ambitious much?

So in all the time I have worked on it, what have I gotten done? Not a whole lot but I'd consider the DeckBuilder to be in a releasable state.

The DeckBuilder started out as a simple card database. I wrote a C# app that parses the Wizards Gatherer website and pulls all the information on every card in every set of every Art (lands, and the Homelands set have multiple arts per card). The information and card images are downloaded and plugged into a relational database that makes it easy to do any query on any part of a cards info. And with all the card information downloaded, there is no need to keep connecting to the Wizards site to get card info.

So with all t
he info nicely contained in the newly named MTGX.db (the x stands for Xtreeeemmmee!! or expansion, w/e =P), I now had to plot out how the program will build up different SQL queries depending on what information is provided. With lots of trial and error to reduce the run time of the queries, I ended up with a pretty fast deck builder, that lets you add cards from your query results list to a deck building list, and save the information off to a .dec file (.dec does exist somewhere but this is my own implementation, I wanted my own file structure). The finished product is this:



I could go in to quite a lot of depth on everything with building just this (and i plan to in future posts!), but this is simply a status of what I have completed so far in the grand scheme of things. The next course of action, aside some last minute tweaks to the DeckBuilder, will be creating the Game Field and working out how to plug in players to control interact with it.

For now I am happy with what I have, and while there is a lot left to do across multiple fields of expertise, I look forward to the challenge.

I plan to do many more posts on this Project and I will likely start with going through what I have done piece by piece, and then following up with more posts on planning the next steps. I hope if you've read this far you'll check back and lend me some feedback in the future :D



 
 
Select a Page:
< 1, 2, 3 >