Monday, November 29, 2010

A danger of hyped releases.

Taking a break from the tutorials for a different kind of post. Ok, in reality I am on the train and have discovered tutorials written for 'web' languages often are heavily dependent on having an internet connection and getting access to API documentation offline is kinda sucky.. so anyway! This is not going to be one my more coherent posts since, well, trains are not the most distraction free environments, but let us see what I come up with.

I have no idea how universally this applies, but I have noticed a recurring pattern in when I tend to stop playing games. Often games that have an update cycle will, from time to time, move from 'little' updates to something 'big'. This big set of changes will often be hyped and talked about for months with speculation about which features will make it in and how they will work.

Now, one of the problems with speculation.. what gets implemented will never live up to people's imaginations. Often the developers will have the same basic ideas but discover that they did not have the time to implement them or the balance could not be worked out or the feature would simply consume too many resources to execute.

This results in a highly anticipated expansion that, for many, is not as good as they hoped. Now, when it comes out, you usually have plenty of people happy with it anyway and many pointing out that people should not complain (which ends up just making the complainers more annoyed… trivializing feedback is rarely a good way to silence it).

So here is what happens with people like me at least. Usually by the time a major update is in the works current features are a little stale, so the hype serves as a reason to 'stick around'…. I tend to get wrapped up in the discussions about features, sometimes even logging on to test servers to get a taste of how things might start panning out. I can see which features are making it in (sometimes, depends on the game and openness of testing) but hold out hope that 'awesome' features make it in. Here is one of the initial problems… I tend to care about features many other gamers do not… I am not a big 'graphics, combat, and scores' person, which is what most developers cater to… so features I am looking forward to usually get cut in order to get those in.

So I walk away with that initial disappointment.. 'skipped over again'. This was a big problem with EVE, every cycle they promises interesting industrial content but it always got pushed off for combat type stuff. When updates are frequent this is not a big issue, but when updates are big and infrequent the next cycle feels very far off, usually interrupted by at least a cycle of working out bugs related to the new features. Thus, disappointment combined with a feeling of hope being a long way off, results in stopping playing.

Minecraft is my current example. Big halloween update that took months (when updates used to be weakly) that ended up containing nothing of real interest.. mostly things related to fighting (which is odd since it kinda sucks as a FPS) and making things more 'hard core' for the score-oriented people. I played it maybe a week after that and just.. sorta… stopped.

Again, I am not sure how universal the lesson is, but the one I take away from this is one should stick to small, frequent updates rather then highly publicized major updates, at least from the perspective of keeping existing players. I think one of the reasons companies tend to like these big updates is they tend to have marquee value.. something big and different to coax in new players or get older ones to return. For minecraft this makes a lot of sense since it is a 'pay once' game.. for EVE I am less sure since the game depends on keeping players over a long haul. So I guess ultimately it will come down to what the purpose of the update….. gaining new players or keeping an existing community happy.

I think.. I think with games like EVE we are seeing a bit of a problem with business models. Even being a fairly seasoned company at this point, subscription games are still a fairly new area that 'conventional wisdom' is still being sorted out. Even as their internal teams figure things out they will have a constant influx of marketers and executives that adjust even slower, and as more jobs are on the line innovation and risk taking tends to decrease.

I think this is something that a lot of these 'Facebook' and similar games have started to figure out since they have less bureaucratic overhead and thus can adapt quicker. As I watch those games (and older ones like pardus), updates tend to be small and fairly frequent, which I think is one of the reasons they tend to have pretty good retention relative to their complexity. The biggest problem they have is people burning through all the content quickly and leaving, which could be fixed by having a larger team and keeping updates coming.

And now I am pretty much out of battery and track, so this seems like a good place to wrap up.

*humms happily* ask not for whom the mp3, may toll it tolls for thee…. your doomed the moment I cease to sing….

Friday, November 26, 2010

jsplatformer Part 1

Ok! First part of this experiment. For this piece I will use Drawing an Image to the Canvas with JavaScript. Let me also take a moment to mention how much I detest those sites that use javascript to alter the text you try to copy out of their page. Creepy.

Anyway. This tutorial goes over the basic task of displaying an image to the page and then bouncing it around. I decided to start with this since it was (a) simple and (b) I already know some flex and believe I can accomplish the same task.

Before I start going over my solution, I want to talk a little about tools. I have never felt it was fair to ask people first learning a new technology to also learn a new IDE at the same time, which Flex tutorials are rather heavy on. So for this I stuck to very basic tools.

For Canvas, I used vim and Safari. For Flex I used vim, Safari, mxmlc (the Flex command line compiler) and Adobe's stand alone player.

Secondly, I want to make it clear, I am a newbie to both these technologies. I am sure there are better ways to do things, built in tools, add ons that make things easier, etc..... I do not know any of these things yet. I am still figuring out what things are needed to accomplish a task and which things are simply things some tutorial author did that LOOK necessary but are not.

Now, on to the actual stuff I wrote. Obviously for Canvas I followed the tutorial pretty closely so the files are only a little different from what was on the page. Sadly I am still working out how to post code to blogger, so the formatting is less then stellar.

For canvas I had three files (including the image)

jsplatformer.html

<html lang="en">
    <head>
        <title>JavaScript Platformer 1</title>
        <script type="text/javascript" src="jsplatformer1.js"></script>
    </head>
    <body>
        <canvas id="canvas" width="640" height="480">
            <p>Your browser does not support the canvas element.</p>
        </canvas>
    </body>
</html>


jsplatformer.js

// target frames per second
const FPS = 30;
var x = 0;
var y = 0;
var xDirection = 1;
var yDirection = 1;
var image = null;
var canvas = null;
var context2D = null;

window.onload = init;

function init()
{
    image = new Image();
    image.src = "file:/./jsplatformer1-smiley.jpg";
    canvas = document.getElementById('canvas');
    context2D = canvas.getContext('2d');
    setInterval(draw, 1000 / FPS);
}

function draw()
{
    context2D.clearRect(0, 0, canvas.width, canvas.height);
    context2D.drawImage(image, x, y);
    x += 1 * xDirection;
    y += 1 * yDirection;

    if (x >= 450)
    {
        x = 450;
        xDirection = -1;
    }
    else if (x <= 0)
    {
        x = 0;
        xDirection = 1;
    }

    if (y >= 250)
    {
        y = 250;
        yDirection = -1;
    }
    else if (y <= 0)
    {
        y = 0;
        yDirection = 1;
    }
}


For Flex, there were a few more files but not many:

Simple1.html

<html lang="en">
    <head>
        <title>JavaScript Platformer 1</title>
    </head>
    <body>
        <object>
            <param name="movie" value="Simple1.swf">
            <embed src="Simple1.swf" width="640" height="480">
            </embed>
        </object>
    </body>
</html>


Simple1.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
  styleName = "plain"
xmlns="source.*"
layout="absolute"
frameRate="30"
width="640"
height="480"
creationComplete="initApp()"
enterFrame="enterFrame(event)">

<mx:Script>
        <![CDATA[
            public function initApp():void
            {
                canvas.init();
            }
            public function enterFrame(event:Event):void
            {
                canvas.onTick();
            }
]]>
</mx:Script>

  <SimpleCanvas id="canvas" width="100%" height="100%" themeColor="#ffffff" />
</mx:Application>


Simple.as

package source {
    import mx.core.UIComponent
    import flash.display.Bitmap

    public class SimpleCanvas extends UIComponent
    {
[Embed(source = '../assets/jsplatformer1-smiley.jpg')]
public static const SmileImage:Class


        private var SmileBmp:Bitmap = null;

        private var xD:int = 1
        private var yD:int = 1


        public function init():void
        {
            SmileBmp = new SmileImage()
            addChild( SmileBmp )
        }

        public function onTick():void
        {
            if (SmileBmp == null)
                return;

            SmileBmp.x += 1*xD;
            SmileBmp.y += 1*yD;
            if (SmileBmp.x + SmileBmp.width >= width)
            {
                xD = -1
            }else if (SmileBmp.x <= 0)
            {
                xD = 1
            }

            if (SmileBmp.y + SmileBmp.height >= height)
            {
                yD = -1
            }else if (SmileBmp.y <= 0)
            {
                yD = 1
            }

        }
    }
}


Ok, enough of the raw code, onto some comments. The core logic is the same, which is not surprising. The differences were more in feel.

Simplicity:

Canvas won when it came to simplicity. 2 code files to Flex's 3, and information was not as duplicated (for instance, the size of the Flex frame had to be put in multiple locations). Canvas was much more 'start up and go', one had to worry much less about how they were going to do things or how to structure their project.

This also gets into my chief complaint about Flex so far. Flex has many ways to do the same things,.. it feels like a language that has been extended over the years in order to accommodate programmers rather then programmers adjusting to it. This kind of flexibility is good for development, but it makes life for the newbie difficult. I went through 3 different flex tutorials, each one did things sufficiently differently that lessons from one could not easily be applied in others, and figuring out why something did not work was difficult because only a few comments might discuss the way that particular author was doing things.

For instance, loading and image. Canvas seemed to have a way to do it, Image() and then set the source.

Flex, first you have 3 different ways to embed an image, plus there were people talking about a 'loader' API you could also use. Images could be (and in different examples, were) loaded as Bitmap, Sprite, FlexSprite, FlexBitmap, UIComponent, BitmapData, or MovieClip. In various examples they might be added directly to the canvas or immediately embedded in a temp container which in turn was added, with no real explanation of why people were doing this.

There is also the issue of mxml vs as. mxml is for layout and UI, as is for logic.. so you have two different syntaxes for the same functionality, with the intent being the mxml syntax makes layout easier while actionscript makes logic easier, but at first glace figuring out why you have to completely different syntaxes for the same language can be a bit confusing.

Explicitness:

Flex was better about explicitness. With Canvas, I guess the whole js file was either converted to a class or processed as some kind of procedural program where it looks for key symbols and links to them. This 'by convention' approach makes things simple, but feels a bit like a big gray room where you are not sure what else might be in there. Flex had things contained within a nice clean class, everything outside language keywords had to be imported (so the split between API and language was much clearer), and entry functions were explicitly defined in the mxml file. You got a much better sense for how things fit into a larger framework.

I admit, I like Flex's explicitness.

Integration:

This one is a good example of 'what do you want to use it for?'. Flex produces self contained applications, either for embedding in a web page or running as a desktop application. All interaction with a larger system probably needs to be done via APIs to things like XMLRPC or sockets. However, Flex has no knowledge of the page in which it exists.

Canvas is integrated into the web page, so you can use the main html page for layout and can pass information (like buttons and forms) from the page to the Canvas. I am guessing this also means the Cavans probably has access to other page information so you can adjust what is going on inside the Canvas according to the page, which might contain other technologies like Django linking to a database.

So Canvas feels like a dedicated web technology designed to work with other web technologies... Flex feels more like Java did... it can be run through websites, but is not really 'part' of them.

Asset Management

Canvas dynamically loads its assets, including pulling them from remote (and remotely managed) locations, and it does this very naturally. Since it is not 'compiled' till someone views the page it can delay as long as possible.

Flex needs to pre-embed images into it's self contained file, so it needs to know ahead of time what each image will be (and seems to convert each asset to a named class?). This brings up the concern of 'what if you do not know till compile time?'... do you need to name EVERY image or is there some way to grab an entire directory? I am guessing there is some kind of html API within Flex for grabbing content off the web and displaying it, but I doubt it is as natural.

So I have concerns about Flex, but these feel like 'newbie/easy' concerns that have solutions later on. Again, Canvas's integration with the rest of a site gives it some clear advantages if you need that kind of structure.

So, this was the very first attempt to compare them. Next up... jsplatformer Part 2!

Wednesday, November 24, 2010

Flex vs HTML5 Canvas

Looking back at this nearly abandoned blog, I can see that I have talked off and on about sitting down to learn Flex. In my defense, I actually have learned bits and pieces of it so it has not been all talk at least ^_^

The point of this post though... which is better to learn? When I ask people this, I tend to get two basic answers.. "Learn Flash" or "Learn Canvas". No one ever seems to recommend Flex, which oddly enough kinda endears it to me.

Flex/Flash seem to have the current mindshare... lots of people using them, lots of tools built around them, lots of help advice out there. On the other hand the are closed source, and Flex suffers from not just duplicate APIs, but finding Flex specific help (as opposed to Flash), esp outside a specific IDE, is hard. Flex also has AIR and a standard player on every machine.

Canvas is new, it is not really standardized (and each browser has its own implementation), a lot of stuff is still missing, help is infrequent, and the APIs are not very mature.

Now, I am not learning this for a job or any particular project.. and I have no time scale... so why not learn both?

For this experiment I have choosen two online tutorials, one for each language..

Matthew Casperson's FlexFighters and.. well... Matthew Casperson's jsplatformer. Hrm, only while typing this did I notice they were by the same person. That should make this more interesting.

Anyway, the idea will be to attempt both tutorials in both languages and get a feel for how the two languages solve the same problems. I guess we will see how far I get.