Experiments in rendering a Tiled Map in javascript/html…

Sophia Game mk1.



Sophia’s first tiles!
Embrace the pixels!

Sophia has been chomping at the bit to make more games. Since it’s been going on two years since I last flexed my gamemaking muscles fully, and since I rather adore Sophia, I’ve been chasing this rainbow.

I’ve been ever more intrigued by the idea of a pure html/javascript game engine of late, and have started taking existing, established tools (like mapeditor.org’s tiled) and putting them into the browser.

Here’s the result: (currently firefox-only). To fully get the pleasure, inspect elements on this example in firebug.

The idea is simple: html/js has affordances baked-in to parse xml documents. This can handle traditional map data. css sprite-sheet techniques have been used for years now, which directly mimic old tilset/vsp-style assets. Combine the two… and you have a effen map. Throw in browser optimizations for visible/hidden elements, and we should have a relatively cheap rendering method.

The above test is fairly simple: one 30×30 map, one layer. It loads instantaneously fast. It’s tiles are a single gif sized 304×144. Fairly economical. I decided to shove each of these boys into a div for now and use the background-image css spriting technique to get a “purist” tiling implementation going.

I opted against using canvas for now because I wanted to see how far I could get without it. So far so good, but I’ve not yet really stressed the system. The next jump will be to take some of my epic 6-layer maps from SotS, translate them into xml, and see how they fair in the browser.

Of the code I wrote, I suppose the “sauce” was a fairly common offset calculation. Although this sort of endeavor may not be so common in the modern age, it’s pretty commonplace to those of us who labored in 320×240 back in DOS. Get off my lawn.

var tileset = {
    tileWidth: 16,
    tileHeight: 16,
    setWidth: 304,
    setHeight: 144,
    
    getCoordsfromIdx : function( idx ) {
        var idx = parseInt(idx);
        idx--; //tmx is 1-based, not 0-based.  We need to sub 1 to get to a proper mapping.
        //idx--;
        
        var perRow = this.setWidth / this.tileWidth;
        
        var x = idx % perRow;
        var y = (idx / perRow);

        return [ 
            -(parseInt(x)*parseInt(this.tileWidth)),
            -(parseInt(y)*parseInt(this.tileHeight))
        ];        
    }
}

This is converting a single tile index into two coordinates for the renderer to consume. For instance, if you want tile 2, it takes a ‘2’ at the top, does some maths, and tells you that tile 2’s offset is 16 pixels in from the top-left corner, and 0 pixels down (ie, on the top row). Some strange quirks of this code: I had to decrement the idx, because Tiled’s xml format is 1-based, not 0 (ie, the first tile, the one at (0,0), is index 1, not index 0); and I negate the two numbers I return because the consumer of these coordinates is a css background-position style, and that’s how they work.

Also of note was a small hiccup when I uploaded this to my server. My sandbox had no trouble serving a .tmx file as Content-Type: text/xml, but my big-boy server threw a conniption about it. I didn’t realize that was a problem until I threw some debugger statements into the code that “should’ve just worked” and found that all of the proper stuff was in the responseText attribute, but responseXML was null. So I renamed the mapfile to .xml on the server and everything worked fine.

I guess next step, before trying to stress the system with a super macho map, is to figure out why this isn’t working in Safari/Chrome/IE/Opera/Whatever…

PHP5, you king of bastards (setting an instance member inside a static class call)

If I’m in an instanced class, and I call another class’s method statically inside of a method in the first class, and that static method should happen to (erroneously) have $this->whatever inside of it…

…it sets $whatever on my outer instanced class.

Here’s some illustrative code:

<?
    class Inner_Static {
        function burrito() {
            $this->_member = ‘A keyboard. How quaint.’;
        }
    }

    class Outer_Instance {
        function taco() {
            Inner_Static::burrito();
        }
    }

    $my_guy = new Outer_Instance();
    $my_guy->taco();

    print ‘$my_guy->_member: ‘ . $my_guy->_member; 

This boggles my mind a bit. Tracking it down cost me a bit of time. Is there actually a sane use for this little tidbit, or am I justified in thinking that a good language would warn you that scope shenanigans are going on here?

Simple scripts always ship.

Simple needs, simple deeds.

A need for a simple one-off occurred Monday evening at work. Some non-engineer coworkers needed to be shown how to make some non-Latin-1 text into html entities.

Basically, they needed a 5 line php script.

Right before sending them to any number of sites that already do this 5-line operation, I decide: what the hell, I’ll just make one of my own. And so, that night after unwinding, I did.

Here’s my HTML Entitizer. Suitable for all your HTML entitizing needs, large or small!

PHP in Escape from &#76;&#46;&#65;&#46;(jokesfornerds)

One of the reasons PHP is so popular is the fact that it’s got so many handy little functions. In this case, htmlentities() is the blade of PHP’s swiss army knife that we’re using. Of course, indiscriminate use of functions like this cause problems like double-escaped characters (&amp;amp;) showing up in databases.

PHP, the swiss-army knife.PHP’s solution to this sort of thing is generally to throw new corkscrews and toothpicks onto it’s ever-growing pile of tools on it’s knife. If you look at the documentation page for htmlentities(), you can see that as of version 5.2.3 of PHP, another optional parameter was added: double_encode. Which will

Getting the right escape order can be hard, especially for novices or small teams inheriting code from other small teams. To date I don’t think I’ve inherited work on a webapp whose database wasn’t littered with extraneous &amp;’s and rogue \\’s. It’s only by virtue of verge-rpg.com having a single developer who is really, really annoyed by this problem the the point of neuroticism that &amp;amp; never appears in the database except in posts that actually wanted to display &amp;.

Although even this level of OCD-database-cleansing didn’t prevent escaping-related errors on the first go-round.

Teh (sic) Implementation.

So, the only time-consuming part of getting this script into my wordpress site (other than me taking a bloody half hour to blog about a 2-minute job) was convincing wordpress that it should allow <?php fragments into my posts.

Luckily, other people before me have wanted this very thing. WordPress’s biggest strength is again one of PHP’s: if you want it, it’s already been made for you. In this case the Exec-PHP module will let admin-level users of your blog post for-reals, actual PHP into your posts! You’d better hope your admins don’t have their accounts compromised! (…one moment. Changing my password.)

In PHP’s case, the code that you want that’ already been written for you is in every single function’s talkback thread. These functions may not be hyper-optimized or the best solution for any given problem, but they generally are what you want to prove a point. You scan the docs, you grab the code, you put it in your site, and you move on to the next problem in your own app.

Quick and dirty, the way PHP likes it.

For the curious, here’s the solution I spat out (copy included):

<h1>Escape html</h1>
<p>This is a simple script to give the escaped codes for some html. Useful
for making foreign languages play nice with html, regardless of how the
server handles string encoding.</p>
<?
if( isset($_POST['escape_me']) ) {
echo('<h2>Your escaped html</h2><div'.
     'style="background-color: #ddd; padding: 8px;">');
echo(str_replace('&','&amp;',htmlentities(stripslashes($_POST['escape_me']),
     ENT_NOQUOTES,'UTF-8')));
echo( '</div>' );
}
?>
<form action='/html-entitizer/' method='POST'>
Text to escape:
<textarea name='escape_me' style='width: 550px; height: 200px;'></textarea>
<input type='submit' value='Create my html entities'>
</form>

(weird formatting so it doesn’t run off the side of the screen; I don’t actually code like that. Mostly. ;)

Coda

It is of note that this tiny amount of effort got me two really sincere “thank yous” from the non-engineers. It’s important to note that things that are mindlessly trivial to a programmer can be tedious tasks to someone without the power to bully the computer into doing labor for them. One of the guys, a computer saavy guy who had access to lists of what each escaped character translated to, insisted that he’d just search/replace the offensive characters by hand.

Ostensibly, this was offered to save me work.

How much time did my 2 minutes of code save him?

(Don’t forget a google for “html entity converter” would’ve saved even that, had I cared to not make the tiny toy script of my own. I’ll ramble on about re-using other people’s work more later, but it’s key to remember even what little work I did end up doing was extraneous and largely an exercise in vanity.)

Split-Testing and Late-Night Coding

When testing a feature wrapped in a spiffy-keen augmentation of an experiment system live, please remember to take into account that you have a 50% chance to land in the “nothing happens” side of the experiment. This will probably save you a lot of trouble.

Experiments!

Split Tests are a very powerful way to determine if a thing you are doing is in your best interest or not. If you aren’t familiar with A/B tests, the very high level is that you show half of your users one thing, half another thing, and you compare the results of each set of users.

Humanity

One of the more mundane, human problems you can run into as an engineer is tiredness. Tunnel vision sets in, and you focus on specific tasks. If you’re solving a complex math problem, you make an arithmetic error. If you’re a coder not using TDD, often you’re running into syntax errors or the like.

These things happen.

Process

At IMVU, we deploy code fifty times a day. The code you just wrote goes out to the production cluster without waiting for QE people to sign off on it, or for your manager to approve it.

Engineering under TDD acts like a blanket to shield you from a lot of problems. You know from the get-go if you broke something in a more interesting way (assuming said interesting way was protected by a test). The tests exist to protect you before you get near the production systems. A failed test on your buildbot is a good thing, because that’s a broken thing your customers never had to deal with. As someone who had jobs where he was tacitly encouraged to code untested fixes on the fly on the production machines in other jobs, this is a godlike boon.

However, things go wrong, and sandboxes and production environments still can disagree! This is why the final step of pushing code live to a production server is always, always, always verify your change manually out in the live website.

And if it’s not verified (or if your change breaks things in very unexpected ways, causing die spikes or high database load or the such), to revert to a previous known good state and investigate further.

Moral

Now that all of the background for tonight is set up, I’ll skip the actual stupidity, and jump straight to the conclusion:

When testing a feature wrapped in a spiffy-keen augmentation of an experiment system live, please remember to take into account that you have a 50% chance to land in the “nothing happens” side of the experiment. This will probably save you a lot of trouble.

It was a pleasant surprise when I looked up to see a wonderful forest around me. I’d just been staring at this one tree over here.

The other kind of Restful

The fun part is my team’s Quality Engineer, who was familiar with this feature and had tested it in production live before, was also up working. He didn’t catch the obvious either, because it was so obvious.

Say a human has a 10% chance of making a mistake/forgetting something obvious. Say he’s got a pairing partner with the same ratio. Assuming an ideal world, you’ve reduced your net error ratio to 1% by having another dude on the case with you. Yay pairing!

If both dudes are tired, their error rates go up, and even pairing, you still have a higher chance of fucking something up. Boo tired!

…Perhaps there’s a better moral than the one listed above hidden in here?

Futility (Duck you, iPhone)

Tim has the wireless card in his room, I assume.

Dare I blog upon my iPhone?

When I got my treo 700 a few years ago, I was pleased. A phone I could write programs for and connect to the Internet with! But soon I would find that coding for the treo was a chore, and while there were some good apps, it’s overall crashiness turned me sour.

I was sad that the irc app was modal (if a call or sms came in, there goes my conversation), but the AIM was kindly persistent. I was annoyed by the lack of options with the camera, at how obfuscated the process to install java was, and how often the phone just hung seemingly frozen for half a minute.

Now I have an iphone. Programming for it turns out to be a pain (Xcode is pretty but inconvenient, obj-c is weird…), the irc apps are still modal, as is the AIM. The camera is slow as dirt whereas the treo was responsive and could take video! There’s no option to run java apps at all on the iPhone, and the device often likes to freeze up for upwards of half a minute.

The treo also could be used as a USB modem, providing evdo to my laptop avoiding situations where one might have to tap repeatedly on a glass screen to make good on blogligations.

It also had buttons to actually press which I could type incrediballt fast upon and would not try to correct me if I ever wanted to say duck.

..Duck you, iPhone.

It also had an sd card slot, just like everything else I pwn.

And it could motherfickinf copy and paste! Can you believe it?

And it wasn’t madeof glass! By the end of my two year contract it was dinged all to shut from uncountable drunken fumbling, but the screen was perfect and it was in solid working order.

…and yet somehow, I wouldn’t go back.

I don’t want the iPhone either, mindyou. I doubt I want the g-1, either.

I just want a smartphone that doesn’t fucking suck.

WHAT? Fucking?!?! You’ll let that through? Duck you, iphone.

Simpletest, Simple Lessons

Learn these lessons, fair reader, so that you may not stub thy code-toe upon SimpleTest!

At IMVU, we use a suite of testrunners and enhancements that sit on top of a core of Simpletest. It’s a pretty sweet suite, filled with all sorts of fancy doodads, gewgaws, and the most lovely selenium fixture you ever did see. Convenience pours out of it’s every pore, as put there by scores of engineers over literally pairs of years.

However, we haven’t spent the time yet to pretty the ol’ girl up for public consumption (which we totally should), so I decided to just use the basic core of SimpleTest while developing (as a personal project) the third iteration of the verge 2d game engine’s website (wip).

I didn’t know what I got myself into.

Here’s some hard-earned knowledge I wrestled from the core of this beasty. These simple statements represent hours of shouting, grunting, and crying defiantly into the rain-filled sky daring a cruel god to strike me down.

SimpleTest Lessons

1. assertFieldById() and assertFieldByName() do not work on html input elements which are improperly placed outside of <form> tags.

2. There do not appear to be out-of-the-box accessors for field values. I had to code up my own getFieldById().

3. If an element has an id, but not a name, it’s value will be inaccessible.

This list is not exhaustive

Learn these lessons, fair reader, so that you may not stub thy code-toe upon SimpleTest! And one day maybe we’ll get around to releasing IMVU’s Sweet Suite of Not-So-Simpletest.

Apologies for a lack of bloodposting for the past few days. I was deathly ill and moving to San Francisco with some guy all at once.

Pair Programming; Pair Administration.

Pair Programming

I like pair programming1.

However, long gone are the days where pairing benefits me personally to a great degree, educationally. These days my pair programming mainly keeps me on-task and away from the dread onset of Nerd ADD, which is itself a Good Thing.

Being the clear Junior in a pair is generally my preferred position; I get to pair with someone who knows a field better than I do and devour their precious knowledge while (hopefully) providing a service to them by keeping them on task and helping to further cement and/or renew their understanding of the subject by taking a teaching role.

Pair Administration

However, when it comes to being a unix administrator, or even a unix shell user, whenever I pair with a peer2 or better I learn new things. And I’ve been a unix user for over ten years and a (admittedly casual) server administrator for over 5 now.

Most commonly, these new pieces of unix and/or shell knowledge come from being the shotgun in a pair programming situation: The driver does some small bit of shell magic, I pull the breaks and ask them to explain what these new, wonderful shenanigans are. Sometimes they’re little things like using !a in bash to repeat the most recent command starting with ‘a’. Sometimes they’re the inner workings of a unix system like editing a fstab.

Some things are necessary to manipulating a unix system. Turns out a lot of what you may personally take for granted isn’t actually in that category.

I’ve seen the same song and dance by observing others as well. Someone does some ‘voodoo’, and the other asks what they did. Knowledge is shared. It seems that unix administration is a lot like living in Manhattan; Local residents will often speak in a secret code exchanging Cartesian coordinates with each other proving that yes, they live here and, hey, maybe you’d appreciate the bagels at this intersection!

Experience Matters!

The important thing to realize here, though, is the strides I see personally in pairing with administration are completely local3. When I was a younger programmer, these information-exchange dances happened multiple times daily. I’ve just become too jaded to see them in my day-to-day operations, because they’re (usually) part of the standard mode of operations. Anything wildly different from my current problems and/or skill sets in software engineer that I hear generally gets discarded as irrelevant to my needs now. However, when I hear something similarly esoteric in a subject I am less close to, I’m all ears: This tidbit sounds interesting, and I should devote my brain to it.

Context is important. The obvious can seem awesome from a certain point of view, and the awesome can seem obvious!

Always Two There Are…

When you pair, there’s generally a tutor/tutee dynamic going on. The more unknown there is, the more “magical” it feels, and the more you appreciate sopping up all that new delicious knowledge. The closer you get to putting your magical 10,000th hour into something, the fewer ‘new’ things you see (or recognize as pertinent).

The important thing, it turns out, is not to dwell on the magical learning revelation sensation. Being the bottom of a pair may feel more “learny”, but being the top is no less good for you. As opposed to “learny” you get “cementy”, “practicey”, and “teachey”.

And sometimes you get to learn a thing or two, too.

That pairing can work for things other than programming shouldn’t surprise anyone, and the fact that pair programming is effective should not be controversial. Pairing is, essentially, a single teacher to single student situation. A master and an apprentice, who can switch roles at a moment’s notice.


1 …Usually. It only works when your pair is being interactive. If a partner is non-communicative, the exercise fails. This can be caused by a driver charging ahead without narrating or responding to questions, or a shotgun falling into torpor and not asking questions.
~
2 Heh. Peer Pairing.
If you like to pair with superiors, you need to parry peer pairing; but you won’t fair well and soon you may say farewell to your fare wellspring of employment. Do not fear peer paring; But do fear pear peeling. The pear peel is fair to the feel and swell for a meal.
…I’ll stop now.
~
3 This is the exact point where I realized my original premise was flawed, and I tried to reconcile it. Had I more time, I think I’d revisit this whole essay from the ground up. I don’t like how the second half of this all goes, currently, but hey: that’s Blogdorf for you.

Review of iPhone App: Scribble

If you want to scribble dicks and show them to people furtively at meetings, it will meet your every need and more!

If you want to scribble dicks upon pictures of people you know, this is your horse.

Otherwise, keep on trucking, sailor.

I was in the doctor’s office today, and just as a Hobbit Hole means Comfort, a doctor’s office means Waiting.

So I pulled out my trusty iPhone looking for some diversion. After catching up on my Twitter feed, I looked around hungrily for something new. I scanned through the games section and tried to buy the Square-Enix iPhone Game only to be told to go bugger off because it was over 10mb in size and I wasn’t on a wifi network.

Balls.

So I went through what apps I had locally, and decided to give the paint app I’d downloaded months ago a fair shakedown. I wasn’t too impressed with it in the past, but I didn’t spend more than a minute trying. And now I had all the time in the world… or at least in the office.

Unfortunately, my initial assessment was correct: MS Paint puts this app to shame.


Scribble’s UI

Colors

In Scribble, you have a finite set of 11 color options. You cannot change them. And while I often will fight the fight of “very limited color palettes create superior art“, the limited color palettes I speak of aren’t 11 colors, and those colors aren’t straight out of the cheapest pack of crayons you can get.

It is not very much to ask that, at the least, palette slots be changeable. Even though there’s no default color picker widget in the iPhone’s api, there are sliders, and there is a handy-dandy keyboard/textfield interface in which you could type hex codes.

Tools

The tools provided are: smallish circle pen, medium circle pen, and large circle pen. And that’s it. No undo, no 1-pixel-size pen, no zoom, no anything other than three pens. While I admire simplicity in design, this goes beyond that. The tools you are given are limited without the ability to zoom in/out and undo mistakes. Without any sort of fine control, this app goes from having a variety of simple image editing/creation uses to being a simple finger-painting toy.

In the gallery below you will see a few examples showing the limitations of the program. The image with dots shows the three pen sizes. The image with large, drawn circles shows the limitations of the interface in picking up on quick movements (note how the circles are very polygonal). The images with logic gates drawn on them illustrates the inability to have much fine-grain control at all, and where a lack of undo/zoom really gets in the way of scribbling down some technical notes.

…Not that most people would really want to draw logic gates for back-of-the-napkin type scribbles, but I needed to draw something and no you may not have all of my extra-awesome secret plans.

Input/Output

One of the better design choices was to save to the Camera Roll, allowing all of your camera-picture-using apps to interface with your hastily drawn pieces of digital refridgerator art. Another nice bit of fun is that it allows you to load a picture from your camera roll as a base for you to scribble upon. This means you could snap a pic with the camera and draw crude cartoon bubbles with a very short word in it over your blokes, or (more likely) disembodied cocks jizzing all over them.

And, really, right there is the killer feature for Scribble.

In the below gallery I took the high road and painted over a picture of my best gal on my couch in a psuedo 80’s pop-deco style. The effect is only halfway there, though since the UI elements prevent me from getting the bottom of the picture covered.

UI

The ui consists of several buttons that cover over the drawing area, and cannot be dismissed. You can get a good gander at it up above in the pineapple picture.

Conclusion

It sorta sucks, but you get what you pay for; This app is free.

If you want to scribble dicks and show them to people furtively at meetings, it will meet your every need and more!

If you want to scribble dicks upon pictures of people you know, this is your horse.

Otherwise, keep on trucking, sailor. Personally, I’m waiting for Deluxe Paint 2e to come to the iPhone…

IMVU is 3d avatar chat; it’s also a pride-inducing piece of software engineering.

Guy whose “About me” page says “I currently work full time on my blog” mocked the place I work for not being a cure for cancer.

Twitter conversing

codinghorror: If I worked on “IMVU: 3D Avatar Chat Instant Messenger & Dress Up Game”, I’d be too embarrassed to blog about it, frankly.

codinghorror: He’s like “our deployment is sweet!” I’m like “dude, you’re deploying a 3d chat game for tweens.” Congratulations, I guess http://is.gd/j4Bh

antumbral: @codinghorror Feel free to ignore the lessons learned by industry leaders like Nexon just because their customers are younger than you.

codinghorror: @antumbral well, let’s just say 3d chat avatar dress-up software was not the cure for cancer I had hoped it would be.

Prestemon: Guy whose “About me” page says “I currently work full time on my blog” mocked the place I work for not being a cure for cancer. Speechless.

What, really?


Jeff Atwood/Coding Horror

What Jeff Atwood is missing the complete point of (in the second tweet) is that the deployment system is sweet, and a successful “3d chat game” requires some amazing pieces of engineering required to pull it off. We have a 3d desktop application, a chat service, a giant catalog, a very high-traffic site, and an always-increasing number of persistent users.

Shame?

As far as what IMVU is: IMVU is a service supplying a need, and making people happy in the process. A lot of people. It’s an MMORP without the rules-based G.

I can speak, however, to being a software engineer at IMVU in much more detail, as I spend many more hours engineering than I do as a user of the service. The number of interesting things to do at IMVU as an engineer is endless: Do you want to work in C++ today and play with the deep guts of 3d implementation and optimization? Would you like to work in python and use a really cool task system? How about some Flash that’ll be used daily by a horde of customers, or the infrastructure to allow those customers to make (and sell) their own flash for other customers to use in the product? Interested in scalability problems and other large-scale optimizations or the infrastructure and strategies needed to allow for making changes to a truly titanic amount of data? Or maybe just work on new and better things that will make customers, real people, happy?

Want to be in a functional business environment yet, as a team of engineers, ship code fifty times a day to a live and heavily used service?

We do these things every day. It’s engineering candyland.

I work at IMVU, and I’m damned proud of it mister Atwood.