First running engine

A lot of progress today, nothing very interesting really.

I got the basic “engine” running, calculating which map cells it needs to draw to cover the whole screen, drawing them, with all their layers, and smoothly scrolling (so I don’t only calculate which cell should be at the center of the screen, I have pixel-level offsets).

It works in full page, automatically adjusts to the page size, just beautiful.

I also added one of my historical arch-nemeses to the code…. Mapping from screen coordinates to map coordinates (or, in other words, figuring out which cell the mouse is hovering over).
Just like 15 years ago, I tried to figure it out, I couldn’t, I searched for it, found it (much faster this time, there was no Google around back then), implemented it, it works, and no matter how hard I try, I cannot for the life of me understand exactly how it works.

I do get the idea… But I just can’t get to the point where I can derive the equations myself.
Which is partly why I have a mysterious “+1″ that I need, and I don’t know why, and it’s killing me inside, but without that, the result is off.
At least it’s “+1″ cell, and not “+7.243 pixels”… So the basics are OK, and it’s tremendously accurate along the edges…
But that +1 is just pure pain for me.

On another front, I haven’t done any performance work yet, although I can’t think of much to do without going to the BIG NEXT STEP, which is reusing the screen and invalidating what’s necessary, instead of redrawing the whole screen for every frame.

Even without optimizing anything, I’m still getting about 50 FPS running full screen (1920×1080) in my PC, and about 20 FPS in both iPhone and Android.
Not too bad for unoptimized code, but it’s not leaving me a lot of extra performance to take advantage of.
I’m going to use a profiler soon, and try to see if a few of the things I’m doing may be killing performance, however, it does look like 100% of the time spent is in blitting, so adding more logic shouldn’t make it much slower, as long as i’m not blitting more sprites to the screen per frame.

Having a larger map is also not a performance problem. It does consume a lot of memory, but it’s not slower at all.

Speed and Memory – Final serious testing, I hope…

To be able to test canvas performance on mobile (and in more browsers), I changed my test page so that, instead of hardcoding my tests to do 1000 tiles per frame, the canvas would fit the whole screen, and the drawing simply covers the whole screen area, as many blits as that would take.
That means that “one test run” won’t do the same number of blits in my PC or in a mobile, and I technically can’t compare one to the other; however, that comparison doesn’t really mean anything anyway, and the amount of blitting I’ll need to do will be dependent on screen size too, so that’s fine.
I also added a nicer interface with a bunch of buttons to test everything in different ways and dump the results to a textarea (instead of my previous approach of using the console).

This is what I found (abridged to conclusions directly, without all the numbers, otherwise it was too long and boring):

Chrome 15 Firefox 8 iPhone 4 HTC Desire S
Baseline 62 FPS @ 1920×1080 (2294 blits per frame)

175 FPS @ 1024×768 (901 blits per frame)

123 FPS @ 1920×1079 (2263 blits per frame)

306 FPS @ 1024×768 (901 blits per frame)

66 FPS @ 480×320 (184 blits per frame) 34 FPS @ 800×400 (364 blits per frame)
Clearing the Screen FillRect a bit faster than clearRect.
Width trick is horrible.
Clearing the screen is the same as not clearing it.
Width trick is horrible.
Clearing the screen takes very little time.
Width trick is horrible.
Clearing the screen takes very little time.
Width trick is horrible.
Blit Source Large / Individual Individual, 5% faster Not much change Drawing from individual canvases is 5% slower than from a large sprite. However, when using toDataURL() images, drawing from individual images is even a bit faster. Individual canvases are the best case, 10% faster than the large sprite
Blit Source Type Canvas
Both images downloaded and toDataURL() images, 50% slower than blitting from canvas.
toDataURL
Images downloaded and toDataURL() images are just as fast. Canvas is impossibly slow (15-20x slower)
toDataURL
Images downloaded and toDataURL() images are just as fast. Also, individual images are faster than large canvas, so we should use this.
Canvas
Images downloaded are 50% slower than blitting from canvas, just like in Chrome.
Drawing semi-transparent Exactly the same as opaque Exactly the same as opaque Exactly the same as opaque Exactly the same as opaque
Drawing off-limits About 4x faster Exactly the same as on-screen About 50% faster About 3x faster
Verdict Individual canvases Individual toDataURL() Individual toDataURL() Individual canvases

NOTES:

  • The baseline case is the closest to what I before referred to as “First drawing test”: blitting directly from the full sprite image, loaded from its URL, and clearing the screen with fillRect. Because of this, the Chrome numbers look horrible. Once you start drawing from canvas, you consistenly get twice the frame rate, and Firefox and Chrome are in the same ballpark. (Surprisingly close actually)
  • Firefox doesn’t get any faster when drawing off-limits. This means I can’t count on this speed-up, which was necessary in one of my laziness indulgement ideas…
  • Android and Chrome are unsurprisingly similar (particularly in the 50% slowdown from images). iPhone Safari, however, is quite different from Android Webkit.
  • I’m very pleasantly surprised at the performance of the HTC Desire! I expected the iPhone to be considerably faster, but the HTC is about twice as fast! That doesn’t seem to show in the table above, but those are the numbers before the 100% speedup from not using images, and also the iPhone is not in “retina mode”, so the HTC is actually drawing twice as much to screen and getting the same FPS. Awesome!
  • It’s a shame that I can’t use the same exact approach for everything. I’d rather have that than squeeze out a few more FPSs. However, canvas is slow in Firefox, and images are slow in Chrome, so there’s no way around it. That said, at least it’s not *too* different. I just have to crop the sprite files into individual cells on startup, and either keep them as canvases or convert them to images depending on the platform. Not too bad. Long live dynamic languages, I guess.

If you want to play around, here is the file I’ve been using. Look at the code to figure out what each button does. Please note that that code is crap, it’s ugly and doesn’t make much sense, I just threw that together quickly to test this. Also remember that that’ll only test the http:// case. Download the HTML file and the .png image it references and try the differences when running from file://.

If you find anything interesting, please do let me know!

Speed and Memory – Firefox and WAN update

Oops!
I was so excited running all my tests and seeing how fast it all went that I forgot to test in Firefox. Big mistake, I needed to check that my weird findings held in FF too, like how to best clear the canvas, how to best draw, etc.

I ran all my tests again in both Chrome and FF, and this is what I found:
(a bit different from the previous results)

Chrome 15 Firefox 8 Thoughts
First drawing test 295 FPS 311 FPS Wow! Firefox is faster than Chrome! Nice
Not clearing canvas 312 FPS 314 FPS Not much difference anymore. Maybe it’s just clearing the canvas that’s faster, not drawing
ClearRect vs FillRect 283 FPS 316 FPS Wow, so clearRect is faster in FF, fillRect faster in Chrome. I probably won’t be clearing my canvas anyway, and even if I were to, this difference is probably not enough to branch the code
“Canvas width trick” 223 FPS 244 FPS Consistently slower. Where is it that the width trick is a time saver?
Individual Tile canvas 316 FPS 17 FPS Uh-Oh! This is a huge problem… I’ll need to experiment deep on this, because I was definitely going the individual canvas route. What the hell??
1000 canvases 226 FPS
20 canvases 311 FPS
Drawing outside 1043 FPS

So… That’s no good. (And good thing I remembered to test FF now, rather than a week later when I would have no clue what the hell was slower)


I made a couple little changes to make sure I wasn’t missing anything stupid, and apparently I wasn’t. It’s also not the invidivual canvases or the “shorter overload” version of drawImage that’s the problem. Firefox is just immensely slower drawing from canvas to canvas, than drawing from image to canvas.

Googling around or asking didn’t really give me much to go on…

I still wasn’t sure what the exact problem was, so I decided to test whether the problem was that this was a canvas (instead of an image), or the problem was that I generated this image myself, somehow…
The only way I could think of testing this was first making my little canvas, and then using toDataURL() to convert it to an image, and then blit from that image.

Problem is… That didn’t work at all the way I was testing, because I just had an HTML file on disk that I’d open (file://), and toDataURL() pukes a huge security exception when you try to use it on a page that loaded over file://.

Fine! I’ll set up a new vhost and test…

And after a bit of work, it worked perfectly. I created a canvas the size of one of my tiles, blitted the tile from the sprite sheet to it, converted it to an image using toDataURL(), and then blitted thousands of times from that newly created image to the “screen” canvas.
That gave me 315 FPS, making it a little faster than blitting from the sprite sheet, just like I had been expecting given my Chrome results. Not as much performance gain as I had in Chrome, but this was still the preferred method.

Suspicion confirmed… Firefox sucks ass at blitting from canvas to canvas. I have no idea why, haven’t found any information about it, and I have no reasonable theory, it’s just 20 times slower.
Good thing I found a workaround! Not just because of the “individual tiles” case, but because I’ll need to manipulate some stuff sometimes, I won’t always be able to blit straight from the image I load from the server.


Firefox solved, let’s go back to Chrome and see if blitting from these “dataURL” images is as fast as from a canvas.

Old baseline benchmark: 316 FPS
Drawing from “dataURL” images: 120 FPS (shit!)
Drawing from my individual canvases: 316 FPS (phew)
Drawing from the original sprite sheet, as I was doing at the beginning: 119 FPS

Wait
WHAT?!?

I triple-checked… That code didn’t change at all. Drawing from the sprite sheet used to give me 295 FPS. Now it gives me 119. What the hell just happened here?

Took a while to figure that out, but… HTTP. That’s what happened.

As soon as I started loading from a webserver instead of file://, image-to-canvas drawing instantly started taking twice as long as before.
I’m guessing it’s slowed down by security checks to make sure you’re not doing any cross-domain shenanigans.

However, canvas-to-canvas performance remained the same. If I take my sprite sheet, blit it to a canvas just as big as it, and draw from that canvas, I get my original 295 FPS. So canvas-to-canvas is exactly the same for http:// or file://

I couldn’t find any justification for this by googling around. I’m guessing that when you draw to a canvas, Chrome security checks the originating image to see if you can draw there, and then when you’re blitting from canvas “it knows it’s fine”?
I’m surprised it doesn’t “cache” the fact that the image is fine and it stops checking… I’m also surprised that this would take so much time, compared to actual drawing. And I don’t even know what the hell is going on in there, it’s all just unfounded speculation…

Whatever the reason, my small little canvas kept working just as fast, so whatever, I’m just happy it works.

The sucky part is that there is no solution that’ll work fast in both Chrome and> Firefox.

So, the apparent conclusion is: When parsing my maps and loading sprites: I chop those into individual canvases, one per cell, and if I’m in Firefox, I convert those canvases to images using “toDataURL()”. The UA sniffing kind of sucks, however, wherever I was going to store the reference to the individual canvases, I now simply store the reference to these individual images instead, and the rest of the codebase is absolutely identical, so it’s not *too* bad, it’s a very localized change.

The other verdict is that it looks like I have no choice but make a better testing page. The plan was always to be able to test on cellphones, which I can’t with this test page as it is, but now that I found this gigantic difference between browsers, I definitely have to.

JS Speed and Memory – Canvas basic sprite drawing

By now, given the ridiculous amount of blogs I follow, I’ve read a lot about canvas. I know what it can do, and how to do it, but theory != practice, and on top of that, most of the articles I read were about “drawing” (paths, shapes, etc), rather than “blitting”, which is all that I’m going to be doing. And while blitting is simple enough, there’s still several things to try, and several things I don’t know, so I need to play around a bit and see how it works…

Basic baseline experiment: I load a transparent PNG image with my sprites, in an , and draw from it to a canvas. Nothing fancy.

NOTE: Below, when I mention “FPS”, that’s just (1 / time taken). It’s how many FPSs I could get, theoretically, based on the limitation imposed by drawing, which I’m assuming is going to be the main bottleneck, by far.

  • Drawing 1000 tiles to a 1200×900 canvas takes 3.4ms (293 FPS).
  • Having the target canvas be on-screen or not doesn’t change anything, if I resize the browser, minimize it, or move it off-screen, performance is exactly the same
  • There’s no flickering, and no image shows up until I finish drawing the last of all the frames in my test, so it looks like I won’t need a backbuffer. And I do need some kind of “stack resetting” mechanism, like setTimeout, at the end of every frame. I was planning to have one anyway, but it looks like it’s not exactly optional.
  • If I don’t clear the canvas between “frames”: 3.2ms (302 FPS) instead of 3.4. That means not only that the clearing takes some time, but also that canvas doesn’t “reuse” existing pixels, meaning it doesn’t save time by only drawing things that changed, just like I expected.
  • If I use clearRect instead of fillRect to clear the canvas, it’s slightly slower: 3.5ms
  • Clearing the canvas using “the width trick” (canvas.width = canvas.width): considerably slower!: 4.4ms
  • Instead of drawing from an image that has a sprite sheet, I tried making a small canvas that has only one tile, and drew from the little canvas to the main one instead. This way, I’m using the overload that only takes x/y parameters, and it doesn’t have to do any clipping, getting only a subset of pixels, nothing, just straight drawing: 3.1ms (315 FPS). Faster! Yes!
  • This last technique obviously impacts memory usage. Baseline Memory footprint: On page load: 6.6 Mb. After creating the little canvas and drawing: 11.1 Mb.

    I then created 1000 little canvases with individual tiles (all the same tile, but that shouldn’t matter), and drew from them (one tile from each little canvas). Memory footprint after that: 23.5 Mb. It does take a lot of memory, but it’s not too bad.
    Also, drawing like this, from a wild number of different canvases, the total test took 4.4ms (222 FPS). So this is much slower.
    All in all, having one canvas per tile still looks like a winner, since there is no way in hell i’ll have 1000 different base tiles in my sprites.

  • However, the fact that having too many little canvases is actually worse for performance throws away another idea I had, which is caching “composed” tiles. That is, if there are a lot of cells in a map that have the same combination of several layers (say, a tree over grass, with a wall), I can pre-combine these and keep them cached, and then I need one blit per cell, not 3
  • I also tested the same thing, but in a more realistic scenario. I created 20 different canvases, and drew one “line” of cells in the screen from each of them: 3.1ms (312 FPS). Still as fast as my original test with one individual canvas. Perfect
  • Drawing outside the canvas: If the destination rect of the blit falls outside the canvas area, drawing is much faster (makes sense really). Drawing the 1000 tiles but where they’re not visible: 0.96 ms (1038 FPS). If I don’t even clear the canvas: 0.77ms (1288 FPS).
    Of course this is not useful at all as an optimization technique, however, it is still good to know, because it may mean I can be more liberal when picking which cells to draw (which is always a challenge in isometric). I can err on the side of safety and make sure the screen is completely painted by drawing a few too many cells, since the once that are outside the screen are extra fast.
  • Finally, transparency… Back in the old days, we’d use “ROPs” to do the transparency (full transparency, not semi-transparency, or “opacity”, which we used to call “alpha blending” and was stupidly slow). You’d “AND” a mask, and then “OR” the image, and you’d have your transparency. Since PNGs support semi-transparency, I wanted to try if I could do something like this and gain some performance. Potentially, this could be a *huge* hit.
    Unfortunately, I didn’t find any information whatsoever about anything resembling ROPs, and apparently there’s nothing like it.
    Also, drawing a fully opaque image (even loading it from a JPG, so that the browser *knows* it’s not transparent at all) takes exactly the same time as drawing an image that has opacity 0.5, and the opaque images with fully-transparent pixels that i’ve been working with so far.

    So… The good news is that nowadays semi-transparency is FAST.
    And the bad news (at least in my old-fart opinion) is that if semi-transparency is FAST, and it’s just as fast as opaque blitting, then opaque blitting is SLOW!
    This is a shame really, because ROP masking was orders of magnitude faster than “alpha-blending”…
    Maybe that doesn’t apply anymore, and now the video card takes care of everything anyway and it wouldn’t be faster, and anyway 300 FPS with 1000 sprites is pretty fast anyway… But still… The little kid in me that used to try all kinds of weird shit to squeeze out a few more FPS is seriously disappoint.

    So, I guess that’s all there is to test here. This is WAY faster than I expected, and things are actually looking very feasible so far.
    It also looks like the time accessing the map is considerable compared to the time drawing, which feels weird, but I was probably testing with oversized maps.
    1000 tiles cover almost 1200×900, so there’s no way i’ll need to read 2500 tiles per drawing, and I won’t have 10 layers, ever.
    One big remaining question is how big is a realistic map… A full screen seems to have an ‘isometric diagonal’ of about 40 tiles, so 1000×1000 is quite a bit of walking, but not crazy huge.
    And the map I tested was pretty big in memory. It may be necessary to do some kind of smart “section loading” if maps get too big.

JS Speed and Memory – array access

First thing to do… Figure out how to store my map. This is going to be the cornerstone of the whole codebase, it’s going to be read and written to a lot, so accessing it needs to be stupidly fast…

Javascript doesn’t have multi-dimensional arrays: I can have arrays of arrays. I can also have hashes instead of arrays. I can have one array, and index it with “[y * width + x]“. Not sure which of these is the fastest…
Also, in each map cell I have a bunch of information, particularly, many layers. A particular cell has a ground level (grass/sand/gravel), possibly a “fringe” element (trees, paths, etc), maybe walls on top of that, and finally it can have objects and/or characters. Since not all cells have all layers, I have the option of leaving empty spots in the arrays, or having all arrays be max length, waste some memory and possibly some CPU cycles traversing them (as opposed to doing an “if” for each layer to see if it’s there or “undefined”).

I also care, obviously, about memory usage.

So these are the things I’ll be playing around with today.


First of all, I need to figure out how to do accurate timing in JS. After a little investigation, it turns out there’s nothing out there. The best I have is “Date.gettime()”, which gives me a precision of milliseconds, in theory, but god knows what’s the minimum interval there…

So I’m going with this:

function time(fn, n, name) {
	console.log("Starting " + name);
	var start = (new Date()).getTime();
	for (var i=0; i < n; i++) {
		fn();
	}
	var diff = (new Date()).getTime() - start;
	console.log(name + ": " + diff);
}

Hardly ideal, and all measurements need to be compared to those of an empty function, to discount the time of calling a function all by itself, and it’s not going to be very precise, but it’s what we’ve got… Also, I’m not really trying to see how long something takes, I’m trying to compare different approaches, so this’ll kind of do.

After playing a bit with this, some things I found out:

  • Initial memory baseline of empty page according to Chrome’s “Tast Manager”: 5.8 Mb. This grows with each refresh, though… Hmmmm… If I restart Chrome, it’s pretty consistent every time, so I need to close all tabs every time for each test. Good to know.
  • Creating a jagged array of 1000x1000x10: 87 Mb, 260ms. That’s huge in memory, but sustainable, and maps will never be that big.
  • I’m estimating I’ll have to draw about 2500 cells in a full screen (1920×1080). Reading the 10 layers of 2500 random cells off of that map: 0.638ms. The time to pick those random numbers: 0.086ms.
  • One-dimensional array (accessed y*width*layers+x*layers+l): 85Mb (same footprint), 391ms to fill (what? slower? this is just a curiosity, though, since I only fill it once). 0.384ms to read 2500 cells. This is a big win, although a bit inconvenient, because the number of layers per cell is not really constant, this will waste a lot of space
  • One-dimensional array for the cells, with each cell having a proper array for the layers: (the most convenient format for me probably) 88Mb, filling 370ms. Reading: 0.724ms What? slower than both? wow. Back to the first version, I guess…
  • Storing only “some” layers (but leaving room for the 10, just gaps in the middle). Then checking for undefined in each layer: 2ms (instead of 0.638, 4x slower)
  • Having the array in each cell be variable length, without gaps: 67Mb, reading: 0.530ms (faster than the original timing, makes sense, less looping)
  • Having each cell store a little “class” with 2 members: 108Mb, read: .731ms. Perfect, because this is just what I need. This is a bit slower than the arrays, but the convenience definitely warrants the little slowdown.
  • Just a little sanity check: Hardcoding numbers instead of using constants in hashes: no difference. phew!

So, to recap… 0.731ms is what it takes to read all the layers (up to 10, avg 2) of 2500 random cells of this map, which is what I believe I’ll be reading for every frame, if I draw the full map each time.
To time this accurately, i actually read 2.5 million cells and are dividing by 1000.
NOTE: I only tested this in Chrome 15.

Firefox 7.0.1: (already on 7?!? When did that happen?)
- Read: 1.3ms
- Reading on the “one-dimensional array for x/y, jagged for layers” was consistently slower (close to 1.9ms), just like Chrome
- Interesting to note that, of that 1.3ms, 0.7ms were spent picking the random numbers. That means the reading of the array is just as fast as Chrome, and I’m wondering why it’s so much slower to generate the random numbers in Firefox…

Firefox 8: (it just happened to update itself. Right now. As i was testing. Cool!)
- Same exact results as FF7. Oooh :-(

Explorer 9: (not that I care about IE for this project, but what the hell)
- Read: 4.1ms (awesome)
- Of which 2ms were picking randomly, so really just 2ms
- One-dimensional array is exactly just as slow
- Quirks mode or standards mode doesn’t change anything (always good to know)

Finally, I also checked to make sure that the names I give to the properties of the class didn’t impact memory usage. I didn’t expect it to make any difference in Chrome, with it’s “hidden pseudoclasses”, and probably not in Firefox either, but to my surprise, it didn’t make a difference even in IE, which as far as I know doesn’t do anything fancy.

So, it seems we have a clear path: jagged array for map cells, and a class for each cell, with an array with holes and of varying length for the layers.

New Initiative… Gaming!!

So, time for a little personal story…

I have always loved coding up games, ever since I was very little. And as it usually happens with hobbies, I started coding many, and finished none (not even close).

But I did try my luck many times. I started when I was 10, trying to write a “conversational” graphical adventure (think Leisure Suit Larry, where you type your commands). Yeah, that was going to happn.
Those were the days of BASICA, where you had to number your lines manually, you didn’t have subroutines (but you did have GOSUB/RETURN, which is basically a GOTO with a stack), and you couldn’t have decent variable names. Actually, for that last one, you could, I just didn’t know that, so all my variables were called a, b, c, until I ran out of them, and started being aa, ab. I had a little manual dictionary to know what they were, obviously. (Hey! I was 10!)
I did get it to actually draw backgrounds and the character on screen which, judging by what I remember about that code, was actually quite feat…

Around 15 I learned what an “engine” was, what sprites were, a few algorithms, and how things were actually done, to some extent. These were my Visual Basic days, when the standard response I got from people was “you want to make games? Learn C++”. And of course, my stubborn reaction was “oh yeah? I’ll show ya!”. I not only managed to make fast enough game engines with Visual Basic (thanks mainly to DirectX, I’ll admit, but hey! It worked!), but also most or all of the things you “can’t do with VB”, like calling the weird APIs in Windows that send you back a pointer to a Unicode string that is actually more pointers to lists of pointers. All printer APIs were like that. Oh, the joy. I also managed to do multi-threading in VB, which was “the big no-no”. So screw that, you can make games, and anything, in VB, thank you very much.

During that phase, I had the beginning of the screen part of a graphical adventure game engine (think Monkey Island), including drawing sprites, with proper z-ordering, and pathfinding when you clicked around. Not a lot, because I quickly got bored, and seriously addicted to Rollercoaster Tycoon, and I moved to my more fun idea, Isometric Game Engines!
So, I made this cute little thing (with graphics stolen from RCT) where it’d actually draw a map on screen, and you could walk around, bump against walls, and I even added some cool “lighting” effects that made it look pretty. Of course, as usual, this is where I got stuck, having part of an engine (what I thought was the hard part) but no real game ideas and that’s where it stayed. But it was a great learning experience, Isometric is complicated in a great number of ways, performance was tough to crack, and I learned a huge number of things.

And then games basically became 3D, completely different arena, where you can’t really make your own engine (and be competitive at least), and where the whole thing revolves around “better graphics” and it just completely lost its appeal to me. That, and work, and stuff, I completely forgot about making games.

And now, something magical has happened. We have handheld devices that are so unbelievable powerful, that they are exactly as fast as computers were 15 years ago. At the same time, the browsers are now competing over who can execute Javascript the fastest, so we have this fantastic language, my favorite by far, that is as fast as VB5 was 15 years ago, but it runs in your pocket!
What this means, in practical terms, is that the most cutting edge games went from looking like this:



to looking like this:



And I can definitely code that!
In my favorite language of all time!
And it’ll run everywhere!

Whoa!
So I’m a bit late, I admit, I should’ve started on this 2 years ago, or 1, maybe… When did <canvas> show up, again?
But I want back!

And of course, Angry Birds is not just the coding; anyone can code that, there is waaaay more to making a game than the parts that I can do myself, so I’ll need partners (or employers), with ideas, and graphical abilities, and all that. And the sad truth is that, just because I liked doing this 15 years ago doesn’t really mean I’m any good nowadays, so I need to learn, and I also need some kind of experience to be believable. And since, as usual, I’m not big on the “game ideas” side, I decided to make a re-take on an old project…



This is what my Iso Engine looked like, more or less… Most of the code has been lost to a tragic hard disk incident a long time ago, but I still have some of the sprites sheets I made back then, a lot of my notes, the maps I had made (in a binary format that is now unreadable, so I’ll have to rely on old screenshots and memory), so I have something to start from.



But there are also a number of other good reasons:

First of all, I already know what I have to do in many ways. I remember or have notes with the math, I know where I want to get to, and I remember this project vividly, so that’s a useful head start.

Also, and mainly, Isometric is one of the hardest of the things you can do in 2D.

  • Drawing to the screen needs way more math than any other visualization type I can think of: which tiles to draw, where to place them, how you move the character, how to know what it is that the mouse pointer is hovering on, etc.
  • It also requires considerably more drawing to the screen. About twice as many blits to fill up the screen compared to a top-view or side-view game. And the drawing is more complicated for the layers to work right (closer tiles occlude farther ones).
  • For the same reason, maps need to be bigger, take up more memory and more CPU to process them.

Basically, if I can make this work, and work fast, I know I can take on any other 2D game and it’ll be simpler than this (at least from the graphical performance point of view).

Since this is mostly a confidence building exercise, both in myself and in others that I may want to work with, and a learning proces of how to make things fast in Javascript/HTML5, it felt like the best choice.

Plus, it’s the most fun I’ve done, by far! Mostly because it’s complicated.

So, i’m porting my old game engine, and this first series of posts will be a bit “stream of consciousness”, as I try to think of the different things that’ll be different between VB5/DirectX and HTML5.
I’m thinking on what kind of memory and performance problems I’ll have, and doing a bit of experimentation.
After that, I guess it’ll just be a report on the porting, and then i’ll start adding new stuff to the little engine, I guess!

I’m intentionally not reading any resources directly related to doing an isometric game engine for HTML5. I did a lot of reading on iso games back then, and now I’m trying to discover things when it comes to implementing games in HTML5 in particular. This is very un-professional, and would be a really bad idea if I were actually trying to ship a game quickly. But I’m doing this to learn, so I plan on reading up on these things *after* i’m done with my port and my own ideas. I also want to see how far I can go by myself.

Oh, and a note on browsers…
For desktop, I’m going to be testing on Chrome and Firefox latest. If I were on a Mac, I’d test Safari too. Not sure how reliable it would be to extrapolate Safari/Windows results to Safari/Mac, so I won’t. I’d also test IE if they supported canvas (for non-canvas stuff, I will, and when IE 10 comes out, I also will). I won’t test Opera or the other browsers because I consider them, sadly, irrelevant. I know this makes me a bad human being, but that’s life.
For mobile, I’ll test iPhone 4 (with iOS 5), and Android 2.3.3, on an HTC Desire S. I’d love to test on more, but these are the ones I have at home.

In the meantime, hope my experiments and posts help someone!