Sunday, July 20, 2014

HaxeFlixel scale modes: complete guide pt. 2: auto-zoom

Part 1: Zoom set to 1

When I started testing the various scale modes available in HaxeFlixel several days ago, I quickly found out that pretty much none of them work as I'd expect. Fortunately, it didn't take long for me to figure out, that it's caused by the automatic zoom calculation that's included in the template, and not by scale modes themself. I mean this:
Both screenshots show the same device and the same code.
So what happened here?

This is the culprit:

if (zoom == -1)
{
var ratioX:Float = stageWidth / gameWidth;
var ratioY:Float = stageHeight / gameHeight;
zoom = Math.min(ratioX, ratioY);
gameWidth = Math.ceil(stageWidth / zoom);
gameHeight = Math.ceil(stageHeight / zoom);
}

So when you set the zoom to -1, the template will recalculate not only the zoom factor, but also your gameWidth and gameHeight. Which leads to a disaster, as those values are used to determine the size of your assets in relation to the game area. So, for example, if you design for 320x480 and prepare a background that nicely fills that 320 px width, you will find out that after launching your game in a different than intended aspect ratio (for example, in landscape rather than portrait orientation), your gameWidth might suddenly become, for example, 100 px, and now the engine "thinks" that it's supposed to fit the 320 pixels wide background not on one, but on over 3 screens.

It might be a good thing for some games, but I'd guess it's bad for most. But perhaps my biggest complaint is that it leads to horribly unpredictable and inconsistent behavior - a game launched in portrait mode and then switched to landscape will look differently than a game launched in landscape and then switched to portrait. More examples below.

Test setup

This is my design resolution.
How does it look on other screens?
Like before, my "test screen" is designed with 320x480 pixels in mind and will be tested in the following starting resolutions (like if the game was launched with this resolution):
  • 640x960 pixels - iPhone 4,
  • 640x1136 pixels - iPhone 5,
  • 960x640 pixels - iPhone 4 in landscape orientation,
  • 768x1024 pixels - non-retina iPad & other tablets
In addition, I'll showcase the following in order to justify saying that zoom = -1 is a trap:
  • Portrait > Lanscape - started in 640x960 px, then rotated to 960x640 px,
  • Landscape > Portrait - started in 960x640 px, then rotated to 640x960 px.
I started from a default HaxeFlixel project template. In my Main.hx, I changed my gameWidth and gameHeight
to 320 and 480, respectively. This is my design resolution. To test different actual resolutions, I modified my Project.xml's <window> tag and/or resized windows on the fly.

My only game state consists of a red background covered by a static 320x480 image (blue). In my design resolution, the background is not visible at all, but in certain scaling modes, it will show up, marking the difference between inaccessible, off-game area (= black bars) and areas that are within the game bounds, just not covered by my image (= red background).

Note 1: As of the time of writing this post and version 3.3.4 of HaxeFlixel, you need the development branch to even think about Scale Modes in the fledgling HTML5 target. A few days ago they simply wouldn't work at all, in the next version, they should be integrated with the master branch and the world will be a better place. What a glorious time to be alive!

Note 2: As mentioned, I found several inconsistencies between Scale Mode behavior on different target platforms. I'll explain them in detail in the following parts of this guide.

Note 3: Don't look at resolutions (they are resized for easier viewing), even though I mention them every now and then. It's the aspect ratios that matter.

Zoom = -1

In this test, I left the default setting of zoom = -1 (in Main.hx).

Click on a thumbnail to change the Scale Mode:

Click in the table below to change resolutions. Make sure to compare "Landscape" with "Portrait -> Landscape" and "Portrait" with "Landscape -> Portrait"!
640x960
(Port)
960x640
(Land)
640x1136 768x1024 Port ->
Land
Land ->
Port

Next


My plan for the next part(s) is to review each Scale Mode individually, focusing on glitches (especially in the HTML5 department), caveats and use cases. Knowing my luck, by the time this guide is finished, it will be outdated, but it's a good thing! It means that HaxeFlixel is improving (and it is, constantly).

I'll post a link as soon as I finish part 3. In the meantime, make sure you read part 1, which shows all the scale modes in action (and working properly!).

Tuesday, July 15, 2014

HaxeFlixel scale modes: complete guide pt. 1: overview

A few days ago I had a bit of a struggle with HaxeFlixel's scale modes and their apparent desire to make my life miserable. Fortunately, there are some wonderful coders out there in the HaxeFlixel community who literally fix things within hours. Right now, I got what I wanted and the scaling works for the most part - although there is still some wackiness and inconsistency in the less used areas, as I will hopefully be able to showcase here.

While I'm not that much into blogging (which should be obvious from my, like, one year or so hiatus), I think an overview of HaxeFlixel's many scale modes is due, especially considering that their official demo is incomplete and runs in Flash - the only platform where scaling is borderline useless. Of course you can compile the demo yourself on mobile or HTML5, but I believe it's simply much faster to look at some images.

Test setup

This is my design resolution.
How does it look on other screens?
The idea behind scaling is that games designed for a specific resolution (in my case: 320x480 pixels, which happens to be the resolution of a non-retina iPhone) should also adapt to other resolutions, for example:
  • 640x960 pixels - iPhone 4,
  • 640x1136 pixels - iPhone 5,
  • 960x640 pixels - iPhone 4 in landscape orientation,
  • 768x1024 pixels - non-retina iPad & other tablets
  • etc.

I started from a default HaxeFlixel project template. In my Main.hx, I changed my gameWidth and gameHeight
to 320 and 480, respectively. This is my design resolution. To test different actual resolutions, I modified my Project.xml's <window> tag PLUS resized windows on the fly - to make sure that it works consistently in both situations (and I guessed right, it doesn't always!).

My only game state consists of a red background covered by a static 320x480 image. In my design resolution, the background is not visible at all, but in certain scaling modes, it will show up, marking the difference between inaccessible, off-game area (= black bars) and areas that are within the game bounds, just not covered by my image (= red background).

Note 1: As of the time of writing this post and version 3.3.4 of HaxeFlixel, you need the development branch to even think about Scale Modes in the fledgling HTML5 target. A few days ago they simply wouldn't work at all, in the next version, they should be integrated with the master branch and the world will be a better place. What a glorious time to be alive!

Note 2: As mentioned, I found several inconsistencies between Scale Mode behavior on different target platforms. I'll explain them in detail in the following parts of this guide.

Note 3: Don't look at resolutions (they are resized for easier viewing), even though I mention them every now and then. It's the aspect ratios that matter.

Zoom = 1

In this test, I explicitly set my initial zoom to 1 (in Main.hx). As you'll soon notice, the "default" automatically calculated zoom = -1 that's set in the template is a trap.

Click on a thumbnail to change the Scale Mode:

Click to change the target device resolution:
640x960 960x640 640x1136 768x1024

Next

In the next part of this overview, I'll have a look at the whimsical nature of Scale Modes when subjected to automatic zoom calculation by an unsuspecting developer, who thinks that something that's been put into the default project template must be pretty well-tested. I have no doubt that some people will think of it as "features", but in my book, something as inconsistent is simply a bug.

Afterwards, my plan is to review each Scale Mode individually, focusing on glitches (sadly there are a few as of now, especially in the HTML5 department), caveats and use cases. Knowing my luck, by the time this guide is finished, it will be outdated, but it's a good thing! It means that HaxeFlixel is improving (and it is, constantly).

I'll post a link as soon as I finish part 3. Read part 2 here. Do it.

Wednesday, October 23, 2013

Color Spree - Resurrection

No, Color Spree didn't get a subtitle.

However, it's been almost exactly 5 months since I wrote that game (in Haxe). It was quite significant for me, because it was the first programming project that I actually managed to complete. And, as a matter of fact, it was the first thing I've done in quite a long time.

And at that point, I decided not to publish the game. So goddamn brilliant.

Anyway, now that I had a few better days, I changed my mind, so I opened up FlashDevelop, fixed some minor bugs and I'm getting ready to post the game on FGL.com.

I didn't change any of the graphics, but I added some really bad music to complement them. Now it's uniformly disastrous.

If FGL doesn't work, I'll just publish the game on a few big sites. One thing I know for sure is that FGL will not work if I post the game now, here. So I'll wait.

I am however going to post a screenshot, even though the game still looks the same as it did last time.

And now I probably should hack Wall Street to get the money for a SWF obfuscator...

Tuesday, May 21, 2013

Two games failed? Make a third

Finally, I have something to show. A preview of a working, functional game. After two failed, unfinished prototypes, I started a new project and this time it looks like it might actually work.

Things I learned.

When making a game, it's natural to start with gameplay - except it completely doesn't work for me, because I tend to lose interest as soon as I have something playable. However, there's a very long road from playable to feature complete, and then even longer to polished.

A gameplay prototype? At best 50% of a game, and that's for a small, free game (the bigger the game, the more polishing it requires). Building interfaces and bug fixing is what kills any entertainment in game making for me. And that's why I never finish anything. Or maybe I'm just lazy and dummmm.

Anyway, this time around, I started with title screens, menus, options, level selectors, preloaders, saves, mute buttons... And honestly - I don't see myself ever getting excited about that kind of stuff. But there was a difference: I knew that once I'm done with that, I had a moderately exciting phase of actual game design waiting for me.

One thing I know I should have done, was to write down a proper code/class design. My programming skills are far too horrible for any kind of "agile development", and yet I continue to make the mistake of carelessly creating illogical code structures, thinking only about the issue directly in front of me. Truth is, I really am lazy and dummmm, so no surprise there.

Here are some prototype screenshots:

The graphics are extremely basic, but I actually like them that way, and it's not like anyone is ever going to play this game except for me and my girlfriend, hue hue.

Gameplay

So, in this (yet-unnamed, although I have a working title - see screenshot above) puzzle/logic game, you click on a square, which spreads its color in four directions. Fill the entire board with a single color of your choice, and you win. Simple? I hope so. Are the puzzles themselves simple? Well...  According to me some of them should be quite, uh, intricate, especially if you want to get the "gold medal" solution, but I'm just a puny Earthling with little imagination, so I wouldn't be surprised if someone found them childish.

To spice things up, you have a limited amount of moves, and - as I should probably mention in the beginning - the spreading of colors doesn't go all the way to the border, but stops on squares (tiles?) that are colored the same, which creates interesting dilemmas, such as: "I want to fill the board with blue, but this particular row would require several clicks of blue squares, but if I first color it red, then I can recolor it back to blue with a single click" etc. Well, that sentence hopefully makes sense at least to someone who played the game.

I start with some tutorial-ish levels, and I also have a few instruction screens, like:

There are also some variations, such as squares that can only be colored from a single direction, or squares that resist coloring a couple of times. All in all, I think I managed to keep it simple enough, but challenging (yeah for sure).

Code

This project has once again demonstrated that I'm a bad programmer. At first, the code looked passable, maybe not very universal, but I didn't intend it to be universal. I was surprisingly satisfied with its structure... until it occurred to me, that I came up with a "great" idea for a new type of square that simply must be in the game.

That was the "coloring-resistant" square. I didn't plan to include it at first, and my code was definitely not ready for it. It broke EVERYTHING - the basic "spread" function had to be patched four times before I was eventually forced to remake it. And since the "spread" function changed, the "unspread" function had to be fixed as well (I curse the day I thought implementing the Undo feature was a good idea). And then the functions and classes that govern the behaviors of special squares turned out to be bugged, so I had to rework them a bit. And by "a bit" I mean enough that I had to change their interfaces... Which were used in the "spread" and "unspread" functions, so I had to rewrite them again.

Loop this about five times and you'll have a picture.

And it's still a bit bugged.

"A bit".

There is a very, very rare bug with the Undo feature that I'm aware of, but unwilling to fix. What I HOPE will happen, is that maybe 1 in a 100 players will face this bug once in the entire game, but probably won't even notice anything (it's not game-breaking). What my objective pessimism tells me WILL happen, is that everyone will bump into this bug early in the game, decide that the entire thing is bollocks and quit.

But I just can't... force... myself... to even think about that code again.

Lesson learned? No. 1) Save great ideas for sequels.
No. 2) DESIGN YOUR CLASSES PROPERLY GODDAMMIT.

Level design

The third lesson learned would be: don't overextend.


My goal is to create 32 levels. And not only that, I also want to make sure, that there is a "great", gold-medal solution, as well as an "OK" solution for every puzzle. This means, that my puzzles need to have multiple paths to victory, and sometimes it really feels like designing two, or even three levels inside of one. Aside from giving me a headache, it will probably also make me look stupid, because I'm sure I'll miss some obvious, three-click solution to a complex puzzle that was intended to be solved in 15 clicks at minimum.

Also, I didn't make a level editor. I mean, am I stupid or am I stupid or what? Somehow, I convinced myself that designing puzzles directly in an XML file couldn't be too bad. They look like this:
    <level nr="9" max="7" great="5">
        <row nr="0">41314341</row>
        <row nr="1">00500000</row>
        <row nr="2">12314141</row>
        <row nr="3">00300000</row>
        <row nr="4">23231322</row>
        <mod row="0" col="2">SPREAD_VERTICAL</mod>
        <mod row="2" col="2">SPREAD_HORIZONTAL</mod>
    </level>
It's an early level, and I already don't want to look at it. And I can't even test the changes easily, I have to actually restart the entire game to re-load the level data, which is a major pain in the ass. Things would be so much smoother with an in-game editor, and as a bonus point, I would have an editor to give to the players! But nope, MS Notepad all the way.

It's ALI... well, not dead.

The best thing about this project, despite its numerous flaws, is that this time around, I am pretty sure I'm going to finish it. This could be my first complete game, not just a prototype, but a fully functional and maybe even entertaining title.

I'm not sure about the way I'm going to handle distribution. I know that sponsorship is the primary source of revenue for Flash games, so I left some space for branding in the layout. It's not actually an ActionScript game, but a Haxe game, which means it theoretically compiles to native mobile apps (and I made it flexible enough to work in any resolution, as long as it stays in landscape orientation), but I don't possess a smartphone for testing, so while I would love to try to make a mobile conversion, I will most likely not be able to.

In the end, I might even skip the sponsorship for this one, integrate some MochiAds, Kongregate API or whatever and just release it into the wild. I don't even have a code obfuscator nor enough cash to buy one (400$? really?), so even that may not be possible.

Anyway, it took me 6 days to get to this stage, and I plan to spend about 6 more days working on levels and general polish. I won't be too terribly sad if I don't make a single buck on this.

Eh, more MS Notepad...