Palagpat Coding

Fun with JavaScript, game theory, and the occasional outbreak of seriousness

Friday, June 29, 2012

What? You're still here?

I just realized that after my last post, I never followed up with a post explaining what I was going to do with my plan to leave Blogger. This, almost two years later, is that post.

Shortly after writing my Manifesto of the Independent Voice, I did indeed go my own way with my tech blog. The result of that experiment, which I called "Tinyblog," went live on my personal/portfolio site, buyog.com, at the end of September 2009. Over the next few months I built out the most important features, and I still add bits and pieces from time to time when I find something missing (I added SEO-optimized URLs about a year ago, for example).

Anyway, Tinyblog (nowadays I call it Spartan) has been a fun little itch to scratch, and whenever I hack on it, I get a little more versed in the plate of spaghetti that is PHP, and there's still some value in that, I think. Would I be happier if I had written it in Node.js or Python or Ruby or some other "hip" web language? Well, probably, yeah, but that was never the point. The point was simply to take control of my professional content... and I've done so.

I said all that to say this: please join me over at Palagpat Coding's new home. I hope you'll enjoy your stay.

Labels: ,

Wednesday, August 04, 2010

Slaying the Beast

So tell me if this sounds familiar:

goal: build up my online portfolio.
how I'll do it: maintain a regular blogging schedule (this, too, I'll write more about soon)

Yeah, not so much. Instead, the past 6 months of my life have been swallowed up by a ravenous beast known as "graduate school," that has grown more and more aggressive in the past 3 or 4 weeks. I dealt it a mortal blow when I passed my defense on Monday the 19th, but it limped along for a while, whispering to me of Target Audiences, Proper Whitespacing, and Nested Bookmarks. Today, I think it finally gasped its last breath, but I have to wait until tomorrow for the official word from the graduate reviewercoroner.

So, this is me saying "I'm back." I have a half-dozen half-finished posts in draft, way more free time than I'm used to, and a lot to catch up on.

See you soon.

Labels: ,

Tuesday, May 04, 2010

JSConf 2010: Final Thoughts and Links

Today I saw in my blog reader that Guillermo Rauch over at DevThought has posted his list of JSConf links, similar to mine (Day 1 and Day 2). He's got a few links I haven't got in mine, but I have some he doesn't, too (he only listed Track A talks). So in the interest of cross-pollination, I've updated my posts and will give him a heads-up of my additions as well, when I can (my work firewall blocks his site for some reason).

Also, in the interest of pointing out other coverage of the best pirate-themed JavaScript conference on the East Coast, here are a few other blogs that have posted cool wrap-ups:

  • Cowboy, a.k.a. Ben Alman, posted this great summary of the talks he attended, complete with photos
  • Kevin Dangoor posted a similar wrapup to his own blog, with some nice commentary on Day 1 talks.
  • Ted Leung did a great overview of the conference as a whole
  • Rey Bango posted a bunch of awesome video interviews he took while attending. Go. Watch. I'll wait.

Oh, and in only-slightly-related news, I'm now on Reddit. Don't know that I'll post there much, but thought it was worth mentioning.

Finally, a note on plans. I think enough people appreciated these "In Case You Missed It" posts, that I'm going to try to keep doing them — at least when the conference interests me. Here are the next few I've got my eye on covering, time permitting:

ConferenceDate
GDC Canada6-7 May
Google I/O19-20 May
TXJS5 Jun
VSLive!2-6 Aug
GDC Austin5-8 Oct
JSConf.eu25-26 Sept

Labels: , , , ,

Sunday, April 25, 2010

How to move to Blogspot and keep your blog on your own domain

Recently faced with the problem of how to have my blogs remain in their pre-existing locations while complying with Blogger's mandatory move away from FTP publishing, I think I've found a pretty easy solution: if you're on a LAMP server (which I suspect most of you are; it's nearly ubiquitous), it's as easy as removing all other index.* files and creating a new index.php file in the appropriate folder, and dropping in these 5 lines of PHP code, changing the URL in the first line as appropriate:

$session = curl_init("http://your.web.address");
curl_setopt($session, CURLOPT_HEADER, 0);
$content = curl_exec($session);
curl_close($session);
echo $content;

cURL is the secret sauce in there, and I could go into a lot more depth, but if you don't need to worry about authentication or anything more complex than a simple page-fetch, there's no need. I allow the post-comments and labels pages to link directly to Blogspot, and I use Feedburner to host my RSS feeds, so this simple solution gets me 95% of the way there. The rest is just resource-management and wise template design.

I love it when something that looks like it'll be difficult turns out to be so easy! But please, if I'm doing anything that opens me up to possible security problems (I don't think I am, but...), please let me know in the comments.

Labels: , , ,

Wednesday, January 13, 2010

Downloads: now with source code

I've fixed the broken links on my Downloads page. So far there are mostly only zip archives with the VB6 source code, with only one app that actually includes an installer. I intend to upload more binaries and/or installers soon; tonight I'm working on an update to Bat'leth that will help me do some work on my grad school project (I'll post more on that effort on my root blog in a day or two)

Labels: , ,

Broken downloads

So a few days ago I posted an update, in which I discussed moving the ancillary pages here on the site to PHP. Part of that update included a link in the titlebar to a refreshed version of my Downloads page, which includes a handful of tools of various levels of usefulness I've built over the years. Well, apparently I made the changes too late at night or too early in the morning, because I forgot to update the links to the actual downloads themselves! I'm at work now and can't access my FTP server, but I'll make the necessary changes tonight so that anyone who wants to download my tools... can actually do so.

Labels: ,

Monday, January 11, 2010

Minor update

Just like I did with my MUGEN blog a few days ago, I've updated this site to use PHP instead of static HTML pages. Not a huge thing, but at least now the site's subsections (currently Canvassa and Downloads) have a prominent location in the toolbar, and all pages on the site (except the blog index, since Blogger can't generate PHP) can reuse the same header/sidebar/footer resources.

Labels:

Thursday, December 03, 2009

Blogger is Busted (or, Hacking your Template to Eliminate the "a[...] is null or not an object" Error)

Earlier this morning, I posted a quick test to see if backlinks are working with Blogger-powered blogs posting to FTP, as I'm doing. Turns out that they're not (note the absence of backlinkage on that page I just linked to).

Now, this isn't a huge problem for me. Would I like the ego-stroking that comes with having backlinks, showing that people like what I'm doing enough to share it? Well, sure I would. But is it worth the pain and hassle? No. So I went into my blogger settings panel, and disabled all the bits pertaining to backlinks, and removed the backlink scripts from my custom template.

Unsurprisingly, this didn't solve the underlying problem -- my site was throwing JavaScript errors! I already knew what was causing the errors: as I said in my previous post, Blogger is auto-inserting some invalid-in-my-context JS code after every post, precisely where the </Blogger> tag lies in my template. Searching around a bit more, I found a solution at Google's Blogger support forum:

Kham Level 1 8/29/09 This has done the trick for me. Wrap all instances of <blogger> and </blogger> with both the HTML and JavaScript comments. <!--/* <Blogger> */ --> <!--/* </Blogger> */ -->

Stupid, stupid, stupid! Since I can't get Blogger to stop inserting the offending code, I have to force it to be commented out! Maybe it's time to take another look at alternative blog engines...

Labels: ,

Blogger Backlinks

The following link is to my previous post; I'm testing to see if that post recognizes it as a valid backlink: Palagpat Coding: Cloning Zelda: And Lo, There Came... an Archive!

A little background: I publish via Blogger's "post to FTP" option, rather than using the apparently-more-kosher Blogspot hosting. Apparently, in late June of this year, other bloggers doing the same thing began seeing mysterious blogs of javascript getting inserted into their published files, most frequently showing up in people's <title> tags, and thus in search results (see for yourself in a Google search for the offending string). If backlinks aren't actually functional in my blog configuration, then I'm going to try turning them off to see if it solves the problem.

Labels:

Wednesday, December 02, 2009

Cloning Zelda: And Lo, There Came... an Archive!

Short update tonight. Bullet points, because I love 'em so much:

  • I've added a few pretty keen new tidbits to Canvassa, and will be blogging about them soon.
  • Speaking of Canvassa, I've revamped the Canvassa Archive page with a more up-to-date (and relevant) development roadmap, including links to all related blog posts on each finished task.
  • Updated and cleaned up the navigation toolbar; it should now degrade better for IE and mobile users.
  • New favicon / site logo. Whaddayathink?

Labels: ,

Wednesday, October 14, 2009

Cloning Zelda: Adding a Title Screen

Legend of Zelda title screen

First, a note on the server move: you may have noticed that my domain was offline for a few days last week; this was because I flubbed the domain transfer to my new server. Anyway, all was eventually straightened out, and I've successfully migrated all of my content from the old server to the new one. If you see anything here on the site that's broken, post a comment and let me know.

Now, on to today's subject: in trying to add several new states to the Game class for Canvassa, I've learned something interesting about Javascript's in operator: it doesn't really work for arrays! More specifically, it does in fact work, just not the way one would expect.

I do a lot of work in Python. In that language, you can do something like the following, and have a reasonable expectation of success:

>>> myList = [5,10,15,20]
>>> print (10 in myList)
True

So in a nutshell, you can define a list of values, and then check a reference value for membership in that list. Simple, and useful. I was doing this in Canvassa's Game class to test for the existence of a caller-specified game state before actually changing to the new state:

    this.constants.states = { overworld: 0, inventory: 1, 
                              dungeon: 2, map: 3, 
                              dying: 4, gameover: 5, cheat: 99, 
                              enum: [0,1,2,3,4,5,99] };
    ...
    changeState: function game_changeState(newState) {
        if (newState in this.constants.states.enum) {
            this.currentState = newState;
            this.drawBG();
        } else {
            console.log("Game.changeState() -- invalid state:", newState);
        }
    }

So basically I was using game.constants.states.enum as a list to keep track of the valid state values that changeState() should accept. Since the states I was using were all 0-based and sequential (except for the "cheat" state, which I haven't tested since Part 2 or so), this worked just fine. But in truth, it wasn't actually doing what I thought it was doing, as I was about to find out (dun-dun-DUN!)

I've been bothered for a while now about how I was loading the quest data (which handles map layouts, item and monster placement, and so on). Basically I was using the dojo.require() function to lazy-load the _quest1.js file, which doesn't actually contain a dojo class definition, but simply assigned the quest data to a namespaced variable, loc.gameData, which my classes could then refer to as a global. All kinds of poor, hackish behavior going on there. Plus, I'm building this game engine to support multiple (and, eventually, user-created) quests, so hard-coding one into the game bootstrapping logic is stupid and short-sighted. In order to correct this egregious flaw in the least destructive way possible, I reasoned, I should add several new states to the Game class, using negative integers to represent these meta-states that exist outside the regular game loop:

    this.constants.states = { title: -1, menu: -2, loading: -3,
                              overworld: 0, inventory: 1, 
                              dungeon: 2, map: 3, 
                              dying: 4, gameover: 5, cheat: 99, 
                              enum: [-3,-2,-1,0,1,2,3,4,5,99] };

In theory, the game engine could now start in the title state, and when the player presses start, change to the menu state, then allow quest selection from there. (for now, I'm simply XHR-loading _quest1.js when the user presses start, and will add the menu state later). But instead of working as I expected, this is when everything started to fall apart. I made the above change and a few others that would direct the game to load the necessary image resources, and then call game.changeState(game.constants.states.title) to display the title screen. BOOM! JavaScript error:

Game.changeState() -- invalid state: -1

Spending some time testing various expressions in the Firebug console, I eventually figured it out: the 'in' operator, when applied to JavaScript arrays, tests for the existence of a given index, not value! Observe this little exchange from my Firebug console:

>>> game.constants.states.enum
[-3, -2, -1, 0, 1, 2, 3, 4, 5, 99]
>>> -1 in game.constants.states.enum
false
>>> 8 in game.constants.states.enum
true

Like I said on Twitter when I discovered this: Freaky! I spent a few minutes looking at ways to get around this apparent misbehavior on JavaScript's part (I've since come to terms with why it works the way it does, but it's totally counter-intuitive to my way of thinking), and found this method, suggested by JavaScript rockstar Jonathan Snook.

In JavaScript, there's an in operator that tests whether a property is in an object. We can actually use this to mimic the PHP function in_array.
if(name in {'bobby':'', 'sue':'','smith':''}) { ... }
If the value of name matches any of the keys in the object literal, it returns true.

Jonathan then offers a refinement via a small function that takes a string array as input, and returns an object literal that can then be tested for membership via in. A reasonable approach, but not really one I wanted to pursue, if something simpler would work. This is what I came up with:

    this.constants.states = { overworld: 'overworld',
                              inventory: 'inventory',
                              dungeon: 'dungeon',
                              map: 'map',
                              dying: 'dying',
                              gameover: 'gameover',
                              title: 'title',
                              menu: 'menu',
                              loading: 'loading',
                              cheat: 'cheat' };
    ...
    changeState: function game_changeState(newState) {
        if (newState in this.constants.states) {
            this.currentState = newState;
            this.drawBG();
        } else {
            console.log("Game.changeState() -- invalid state:", newState);
        }
    }

Et, voila! Simple and elegant. I still have my pseudo-enumeration of valid game states, but I've eliminated the unnecessary "enum: [1,2,3...]" construction, and changed the state values from meaningless integers into strings that matched their own keys. Now my code can still refer to states via their game.constants.states.* enumeration values, and in works as expected, since those strings resolve as properties of the game.constants.states object literal.

There was a little more code cleanup necessary to support this change (for instance, I had to define a list of "unpausable" states so that the user wouldn't be able to put the game in pause mode from the title screen), and there are still a few lingering, unrelated problems in the 0.5 codebase, but we now have a title screen, and the ability to add new game states and check for their existence. All in all, a good night's work.

Labels: , , ,

Friday, October 02, 2009

Cloning Zelda: Progress and a Change of Methodology

So those of you who are hitting the work-in-progress Canvassa build may have noticed that I've added sound support back in. It's not very Dojo-y at the moment, but I got tired of not hearing anything as I tested, so it's in. I've also got the bug about predefined items (e.g. the sword on screen 1) reappearing after you pick them up.

The other major change in the Canvassa effort is how I'll be measuring progress. I started out treating it almost as a tutorial of how to build a game like this in JavaScript+Dojo, and to a certain extent I'll continue to do so, but the posts will stray from the "Part 1 / 2a / 2b..." format that I've been using, and go to a slightly more traditional "dot release" approach: right now I'm working on version 0.5, and when it's finished and the Github repository is updated, I'll move to v0.6. All development will be done in the work-in-progress Canvassa location, so no more Part 1 / Part 2 / etc. subfolders. Hopefully this will be easier for me to work with and stay on task, and will be more in line with what you, my faithful reader, would want to see anyway. (of course, if I'm wrong in my estimation, feel free to let me know in the comments).

Beyond that, not much else has progressed this week; I'll be moving this blog and my others to my new host soon, and I'm still trying to decide how exactly I want to set things up (one of the main points of uncertainty is whether to keep the three blogs separate, or merge them into a single stream with tags/categories to differentiate them. If I do merge the blogs, I'll keep my RSS feeds the same (I'll re-orient the FeedBurner links to point to the appropriate places), so those of you reading me through a feed reader probably won't notice much of a difference. Hopefully, I'll be able to get the buyog.com domain transferred over smoothly to my new host as well, but if not, the buyog.net domain will get you to the new content. When the move actually happens, I'll make a note of it here so you're all aware.

Labels: , , ,

Wednesday, September 09, 2009

Cloning Zelda: Back-to-School update

After taking a sanity break from my JavaScript/HTML5/Canvas Zelda clone I've been making for the past several months, I've started banging on it again, but haven't been able to muster the energy to actually blog about it, perhaps because the things I've been doing aren't all that technically interesting, just important to do (case in point: I've had the bow & arrow working for a while, but until yesterday's update, it wasn't tied to your rupee count as it was supposed to be). As of this morning, the sword, boomerang, bow, and magic wand are all working more or less as they should be (you can't throw the boomerang diagonally yet, and the wand produces magic waves without you actually waving it, but those are both minor quibbles like the arrow-rupee thing), and I've implemented a cheat code to grant you all items so you can actually, y'know, test them (hint: it uses the Konami Code, or you can just mash the "ALL ITEMS" button down in the corner of the screen)

A couple of the remaining items, however, promise to be interesting: bombs and candles both behave differently than standard projectiles, and the flute, bait, and letter aren't projectiles at all (well, I suppose you could think of the bait as a projectile in the same way that the bomb is, but still... it doesn't actually kill enemies, just attract them). Each of these has the promise of interesting blog fodder:

  • bomb: drop a bomb, and after a moment it spawns multiple "explosion" artifacts
  • candle: spawns a flame projectile, but it only goes a limited distance and not clear across the screen like the others
  • flute: spawns a whirlwind object that picks up the player and warps them to the location of the dungeons
  • bait: like the bomb, since you just drop it instead of throwing it -- but it doesn't explode or kill the enemies, it just alters their AI behavior
  • letter: causes the old lady NPC to sell you medicine
  • medicine: refills your health and then self-destructs

So as I implement these remaining items, I may jot some notes about why each is interesting to implement, and then I'll have something worth talking about here.

Meanwhile, go see the stuff that's already done here

Labels: , , , ,

Tuesday, July 14, 2009

Hiatus?

Quick Tuesday post this week, with a request for feedback embedded at the end.

I'm posting this from work while on my lunch break. Last Friday, something of a dam burst here at work, and I'm now flooded with work to do, where a week ago I was a little light on projects from time to time. This has the side effect of giving me less time to think about the content I'll be producing for the site here... although I actually did the vast majority of my blog work "off the clock", there were lulls where I could at least brainstorm solutions to problems (like the whole "Math Wall" thing, for example) -- now, not so much.

On top of this massive shift in my work environment, I spent last weekend moving my family into a new home / state / city / etc. This means a home new internet provider is necessary... and they won't be able to come and hook me up until this coming Friday. So... the big loser in all of this is my blogging. Once my home internet is up and running again I should be back in business, but until then things are, sadly, on hold.

Now, to that request for feedback I mentioned at the beginning of this post: I've recently set up a new domain at buyog.net, and have installed a WordPress-powered blog over there. Here's the question: should I merge my three Blogger-powered blogs (Buyog's World (the root blog), Buyog's Lair (the MUGEN blog), and Palagpat Coding (this web programming/gaming blog) into a single master blog, separated by categories? The content of these three blogs, and presumably the resulting audience for each, seems to me to be so diverse that merging them would be counter-productive. But I'm interested in seeing what people think. Let me know below in comments, or feel free to email me at buyog2099(at)gmail.com.

Labels:

Wednesday, July 08, 2009

Watch this space

I know, I'm late again with my weekly Tuesday update, and for that I apologize. The short explanation is that I'm moving this week, so am very much in the thick of packing right now. I have Part 6A of my "Cloning Zelda" series almost ready to go, but haven't had the time to write it up right, yet. I'm shooting to get it up before the move this Friday, but if that doesn't happen, look for a more-substantial-than-usual update next week.

Labels:

Tuesday, May 12, 2009

Sticking to a schedule

For the past month or so, I've been following Chris Guillebeau's blog and Twitter updates thanks to a link from Seth Godin. Even though the stuff these guys talk about has little or nothing to do with my "bread and butter" sources of income (computer and linguistic consulting), I find it fascinating to see how people transforming the collective zeitgeist about what a "career" can and should look like for our generation. Highly inspiring stuff. Case in point: in his recent publishing sensation, 279 Days to Overnight Success, Chris suggested that bloggers who, like myself, aspire to extend their personal reach, should establish a regular publication schedule for that blog. So, that's the main point of this post, which I'm going to cross-post to my root and MUGEN blogs as well.

Moving forward, I'm going to try an experiment, and we'll see if I can stick to it. If so, I may expand it out at some point, but this is probably a good place to start:

  • Sundays: I will post something on my root blog
  • Tuesdays: I will post something on my code blog
  • Fridays: I will post something on my MUGEN blog

I do have a new post brewing for this blog (next in the Cloning Zelda series), but it's not ready yet, so it'll most likely wait until next Tuesday to kick off this new schedule.

Labels:

Friday, April 24, 2009

JSConf 2009

As I mentioned on my main blog, I'm attending a local JavaScript conference today & tomorrow with a couple of co-workers. Some great, great stuff today; I tried to tweet about things as they happened. Yes, as I mentioned a few days ago on the root blog, I've finally taken the Twitter plunge. My tweet stream, or whatever you call it, is here, and I've also added a "latest tweet" widget and a twitter icon to the sidebar to the right. On site-related news, I should have something to post pretty soon, now that my other commitments appear to be winding down a bit.

Labels: ,