Would you pay to have your app reviewed?

Original Author: Kyle-Kulyk

I’ve been gaming about 30 years now, ever since that Commodore Vic-20 made it’s appearance under our Christmas tree back in 1981-82. Video games have been a passion of mine since well before I decided to try my hand at creating them as a profession and during these past 30 years, video game reviews have evolved just as the games they reviewed. Back then, if a game shipped broken, it shipped broken. There was no patching, no do-overs so I relied on print reviews to help me save my money and time from busted games. Not to say I still wasn’t duped into buying a broken game from time to time (I’m looking at you, Atari ET. How many hours of my childhood were spent in those stupid pits?) but generally I trusted game reviews to help set me on the right path when it came to spending my gaming dollars. Today the internet is awash in review sites.

Now as an innocent kid sneaking a peek at the latest review scores from a magazine at a rural pharmacy, it never occurred to me that companies could be paid for these review scores. Certainly, over the years and with the rise of the internet there’s been much more talk of review sites and publications taking money in exchange for their reviews. It’s hard not to look at a review score on a site that’s pretty much one giant advertisement for this game or another and wonder how much money has exchanged hands prior to the review being written, and how could that not on some level influence the review in question. The internet seems to be in general agreement. Accepting money from game makers for reviews could potentially compromise that review and is, to put it bluntly, a bad thing. Then there’s app review sites.

After launching our first mobile game, Itzy3d, on Android and Iphone in Jan this year, I next set about the daunting task of trying to get our little game noticed. I wrote up a press release, sent this to various PR sites and then set about contacting as many review sites as I could find in the hopes that someone would have a look at our game and, for better or worse, inform their readers of their opinion of the title while the rest of our team started work on our next title. Over 200 emails went out with a short blurb about who we were, what our game was about, a few screen shots and our desire to have our game reviewed.

Almost immediately I started receiving replies from sites, and the average reply would go something like this. “We have a lot of submissions and may not get a chance to review your game. Send us money and we’ll be able to do something for you.”

Now at first I was dead set against this. Paying for reviews? The entire notion just struck me as wrong. I thought reviewers had a lot of testicular fortitude to even suggest I spend money on their opinions. But then more emails came, with more offers for “expedited review services” for a fee. Some offered up advertising as well as a review to add value, but when questioned about click rates, monthly visits and the like, the information I would require in order to make an informed decision on where to spend my advertising dollars was almost never forthcoming. Just send us money. At some point I realized that this wasn’t just a few sites looking to cash in on desperate app developers, asking for money in exchange for app reviews seemed to be the norm. After waiting for weeks for someone, anyone to review our title, reluctantly I opened my wallet and paid for a few reviews. Obviously, I had to pay if I wanted to play their game. The reviews from users on the Apple and Android app store had been very positive, but what we were hoping for was a detailed, well thought out review that could give us some feedback and maybe boost our visibility. I paid for 4 reviews. Two were helpful, one was ok, one just took our blurb from the press release, put it up on their site and slapped 3 stars on it. Of the $100 out of my own pocket spent for reviews, the 200+ initial emails sent out, the follow-up emails and the odd correspondence between myself and review sites, we ended up with 6 reviews, 7 if you count the site that simply slapped a score on our press release.

I resigned myself to the new fact that app sites generally existed to fleece ignorant indies out of their money and given my experience vowed that I would not waste my hard-earned dollars on review sites ever again. Last month, I happened across AppyNation’s: Hall of Infamy. It was a list of sites that engaged in the practice of accepting money in exchange for reviews and encouraged developers to add to the list as they came across sites doing the same. All I could think was, “But don’t most app review sites do this?” Certainly based on my experience with the hundreds I contacted, sites taking money for reviews seemed rather the rule than the exception. Pay or we’ll ignore you completely.

App review sites. Like headcrabs for your wallet!

In a months time (fingers crossed) when we’re ready to launch our next title, Vex Blocks, I’ll still put out a press release, I’ll still attempt to raise awareness of our title anyway I can but you can be sure I’m not about to hold my nose and shell out for any more “expedited” reviews ever again. It didn’t improve my game’s visibility, it didn’t push more downloads – it was simply a waste of money. It shouldn’t be the norm for review sites to ask for money for their reviews. As the indie development community grows, these sites will continue their parasitic ways by preying off developers desperate enough to throw what limited funds they have away in the hopes of giving their game a better chance of success. If a site is reputable and getting decent traffic in the first place, they don’t need your money from reviews. I was fooled by thinking this was the norm simply by the sheer amount of sites doing this. Don’t prove another willing host as I did.

Windows x64 ABI: Stack Frames

Original Author: Rich Skorski

In the previous post, x64 ABI: Intro to the Windows x64 Calling Convention, I explained the rules of the Windows x64 calling convention.  Now we’ll take a look at what makes up a stack frame.

 

Disclaimer

All of the disassembly I’ll show you is from Visual Studio 2012 Express.  Comments I make about MSVC are referring to that version as well.  If you’re following along at home with 2010, you won’t see any differences with the compilation of my example code.  I’ve seen 2012 store non-volatile registers in function prologues and take advantages of tail calls more often, but these are simple examples and result in the same disassembly so long as you use the same compiler options.

 

Stack Frame Anatomy

This is what the common Windows x64 stack frame looks like without optimizations.  The stack grows upwards, and the numbers in the block are the sizes that it can be:

The space between the dotted lines is the stack frame, the memory a function owns on the stack.  Each function is responsible for creating and destroying its own stack frame.  They are also responsible for the memory used by parameters they pass to other functions, so parameters are part of the calling function’s stack frame.  This means a function will have to access the memory below its own stack frame to get at its home space and parameters numbers 5 and up (read the last post for a refresher on what the home space is all about).

 

The Stack Pointer

The stack pointer, RSP, doesn’t move around very much.  It will only change when functions that dynamically allocate stack space are called (like alloca) and during function prologues and epilogues which create and destroy the stack frame respectively (read this for a definition of prologue and epilogue, the body is everything in between).  In the body of a function, RSP will usually be 16 byte aligned.  The promise that needs to be kept is that the alignment of RSP will be known when you enter a function.  If you don’t call another function, there’s no reason to keep that promise and the compiler can put RSP on whatever alignment it wants.

RSP won’t be on 16 byte alignment after the call into a function because calling a function pushes an 8 byte return address on the stack.  But since it was aligned before the call, its value is still deterministic.  RSP will always have a value ending in 0×8 in the prologue.  Same goes for the epilogue when it restores RSP back to that value before returning (ret pops the 8 byte return address off of the stack).  I like to call this a 16+8 byte alignment.  There might be an official fancy term for it that already exists, but I don’t know it.

To summarize: functions that call other functions must always have a 16 byte aligned stack pointer in their body.  Functions that don’t call any other functions don’t have to keep the stack pointer on any specific alignment.

Alloca makes 16 byte aligned allocations.  The top of the local variable block is also aligned to 16 bytes.  16 is the number though shalt align to, and the number for the alignment shall be 16.  That’s the reason for those orange blocks, the padding to keep these blocks of memory aligned.  The one higher on the stack only exists if the maximum number of parameters passed to functions is greater than 4 and is an odd number.  The existence of the one lower on the stack depends on the size of the non-volatile register save block (including the frame pointer) and the size of the local variables block.  Its home is between those two blocks.

Sometimes that lower orange block is 16 bytes, and I don’t know why.  The cases where I’ve seen it happen, no saved registers with 24 bytes of local variables is the simplest,  the compiler could have had a 24 byte local variable block with the top aligned to 16 bytes and no padding at all (the last 8 bytes would be taken care of by the return address pushed on the stack).  Maybe there is no purpose, and this is room for improvement for the compiler.

Aligning all of these pieces might be the best thing since sliced silicon!  It lets the compiler easily align local variables.  It can also easily determine if aligned SSE load/store instructions can be used or not.  If RSP wasn’t aligned, the compiler would have to always use the unaligned instructions or add alignment code to the prologue of certain functions.  Aligning every stack frame is an elegant solution, and I think the extra few bytes of padding is a small, worthwhile price to pay for the ability to use optimal SSE instructions. Those instructions can handle data in any format, not just floating point numbers.  You might see the compiler use them to move 16 bytes of data quickly.  Since the SSE registers are sure to exist and stack data can be aligned, there’s no reason to use the x87 FPU instructions (unless you REALLY want that precision).  For x87 the bell tolls.  Time marches on.

 

The Frame Pointer

The frame pointer is not always used.  If the stack pointer doesn’t change within the body of a function, it’s not necessary to remember where it was previously.  The function epilogue already knows how to restore it before returning.  If you use alloca, RSP will jump around and RBP will be used as a fame pointer.  Instead of remembering how far RSP moved during the body of the function, the compiler uses the frame pointer as an anchor point to restore RSP before returning. RBP is always the register chosen to be the frame pointer.

I’ve also seen MSVC use a frame pointer for reasons that I am admittedly uncertain of.  From what I can tell, the frame pointer will be used if a function needs to pass enough struct parameters by-value and the amount of stack space needed for the temporary objects is within a certain range (the structs section of the last post explains those temporary objects).  I think there’s a required ratio between the number of params and their size.  IE:  6 structs of 8 bytes, but not 3 structs of 16 bytes.  This magic is interesting, but the specifics about how it works are not important for this post.  The lesson to take away here is that MSVC may decide a frame pointer is necessary for reasons other than the use of alloca.

**UPDATE 10-2-2012**

In the above situations, I think the compiler decides to use the frame pointer to avoid using longer MOV instructions.

 
  mov    rax,qword ptr [rsp+100h];7 byte instruction
 
  mov    rax,qword ptr [rbp-4h]  ;4 byte instruction
 
  

So the compiler decides that the benefit of using the frame pointer outweighs the benefits of having an extra register. Since there are a good number of regsiter, I can’t argue against that. Way to go MSVC compiler team!

I’ve noticed similar behavior when passing literal constants to a function, but didn’t know why it was doing it until now. Make a function with enough parameters in there so some have to go on the stack. Just by changing the values you pass, you can see the instructions change. You may find it move a constant directly to the stack, or move to a register first and then move the register to the stack. It may not always do so because the size of the instructions is smaller, but because it can use 2 separate instructions that can be piped together by the CPU.
**END UPDATE**

Predicting where the frame pointer will point to is a bit tricky.  It often points to the top of the local variable block, but it can be anywhere within that block.  If that block doesn’t exist, it would be pointing to the top of the saved non-volatile register block (which I guess you could argue is the top of the 0 sized local variable block).  There’s no alignment requirement for the frame pointer, so don’t be surprised if you see it with a low byte of, say, 0×9.

Some folks may use the term base pointer instead of frame pointer, and since EBP might point somewhere in the middle of the stack frame I’d say the former term is more fitting for x64.  I’m going to continue calling it a frame pointer though, because that’s what I’ve always called in and that’s what the MSDN calls it.  That’s the way it is, and that’s the way I likes it, dagnabit!

Since the frame pointer isn’t always used, the linked list of frame pointer and return address pairs going up the callstack doesn’t exist like it did on x86.  It sort of exists if every function used the frame pointer, but it still wouldn’t be as easy to follow since there’s a varying amount of space between the address it points to and the address where the last frame pointer is stored (if you have no local variables and only RBP is saved, you’ll get lucky and have the same setup as x86).

It’s still possible to follow the callstack yourself with or without a frame pointer, though.  Once you find the prologue or epilogue for a function, you should be able to calculate where the return address is as well as the bounds of the stack frame.  With the stack frame diagram in your hand and the song of debugging in your heart, you should be able to find everything on the stack.

 

Non-Volatile Register Block

The difference between volatile and non-volatile registers was briefly explained in the last post. The non-volatile registers need their values stored before a function uses them, and this block is where they go. It won’t store all the registers. Only the ones it will wind up using will be stored by the prologue and then restored by the epilogue.

The integer non-volatile registers are usually stored on the stack with a push instruction that happens before the stack grows (sometimes they’re moved the home space instead, and that can happen before or after the stack grows).  If RBP is used as the frame pointer, it will always be pushed and it will always come before the others.  That’s a handy rule to have because it keeps the old frame pointer right next to the return address.  I’ve always seen these registers pushed in a particular order: RBP, RBX, RSI, RDI, then R12-15 sequentially.

The SSE registers can’t be pushed, so they will always get moved to this block after the stack grows.  I’ve noticed that the order in which they’re moved follows the register numbering order as well.

 

Local Variables Block

This is where local variables go on the stack, but there are some other bits that go here, too.  If you take a data type that is greater than 8 bytes (structs or SSE types) and pass them as by-value parameters, then the calling function will create temporary objects that’s placed in this block (getting that temporary to the called function was explained in the last post).  You can think of these temporary objects as local variables that the compiler stuffs in there for you, which is one reason why there isn’t a separate block in the diagram for them.  The same thing happens for temporary return objects that are greater than 8 bytes.

There can be alignment padding sprinkled throughout this area, too.  Data types that are less than 8 bytes data types can be packed tightly together by the compiler, so padding should be put to good use when able.   Don’t expect the order you declare your variables to dictate where they are on the stack.  That’s another reason why there’s no “temp object” block.  There would be a variable number of temp and local variable blocks weaved between each other, and that makes for a very messy picture.

I’ve yet to see a function preserve volatile registers before making a function call.  If it needed to, my gut tells me that there would be space in this local variables block for saving those registers.  Just like the trick for large pass-by-value data types, it’s another temporary variable added by the compiler.  In my experience, the compiler has always been able to use one of the non-volatile registers to preserve values across a function call.  It certainly could store volatile registers before a call if it wanted to.  But in order to force that situation, there would need to be an instruction that operated on more than the number of non-volatile registers at once (forcing the use of a volatile register to store one of the required values).  So long as such an instruction doesn’t exist, it’s possible for the compiler to avoid the situation entirely.  The MSDN doesn’t explain how these registers are saved, which gives me more confidence that the situation won’t come up.

 

Home Space and Extra Parameter Block

These blocks are contiguous, so all the parameters are right next to each other in order.  A function will always keep these at the top of the stack so that they are directly below a called function’s stack frame.

They’re added to the stack frame in the function prologue, and always exist at the top of the stack frame. So if alloca is used within a function they wind up moving. That means that the address of these blocks for one called function will be different than the address for another called function if there’s an alloca call in between.  This isn’t a super important fact to remember about the stack frame, but it may help you on your debugging adventures.

 

Stack Frame Size

If you have a very boring function, it may not have a stack frame at all.  It has to be VERY boring though: no local variables, no calls to other functions, no dynamic stack allocations, and no use of non-volatile registers.  Each one of those requirements eliminates the need of one of the blocks in the stack frame, so if you satisfy all of them the whole frame can go away. Sure, you still have the return address, but is that enough to call it a stack frame? I would argue that it is not.  These kinds of functions are called leaf functions.  Break any of those conditions, and you got yourself a stack function.

Brief aside: The definition for a leaf function above is the definition you’ll find in the GNU documentation.  This confused me at first, because I figured a leaf function would only have the attribute of not calling any other functions.  I think the definition these compilers use is silly, but I will conform to their definition to be consistent.

The size of the stack frame varies, but it will only be made up of the parts in the diagram at the beginning of this post.  Since RSP doesn’t often move in the body of a function, you can usually look at the prologue to see how much it adds to RSP and count the number of pushes before it to get the stack frame size.  If you use alloca, add up the sizes and don’t forget to account for alignment padding.

The space for parameters number 5 and up for called functions, the lighter blue block in the diagram, is allocated up front in a calling function’s prologue. The compiler goes through a function, looks at all the function calls made, and takes the one with the most parameters.  That’s the number it will use when determining how big this block should be. The home space must exist in a function’s stack frame if it calls another function.  Otherwise, it can be removed entirely even in unoptimized builds.

If you recall, I had said that every function call requires at least 48 bytes on the stack.  Let’s look at a function that does nothing but call another function with no parameters:

//important compiler options: /O2 /Ob0 /GS- /Gy- /GL-
 
  
 
  __int64 g = 0;
 
  void NoParams()
 
  {
 
    ++g;
 
  }
 
  
 
  int main()
 
  {
 
    NoParams();
 
    return 0;
 
  }

And the disassembly:

NoParams: 
 
    inc    qword ptr [g] 
 
    ret 
 
  
 
  main:
 
    sub    rsp,28h
 
    call   NoParams
 
    xor    eax,eax
 
    add    rsp,28h
 
    ret

We’ve taken out all of the optional stuff, and we’re almost able to call this function VERY boring based on our definition from earlier.  But lo!  It adds 40 bytes of stack just to make that call.  32 of those bytes are for NoParam’s home space.  The other 8 bytes are padding to align RSP before the call to NoParams.  As explained earlier, main knows that RSP was on a 16 byte boundary before main was called.  Calling main pushed an 8 byte return address onto the stack, so adding 8 more bytes puts it right back on the 16 byte alignment.

Add all that up and you get our magic number: 8 bytes of padding to align RSP + 32 bytes home space + an 8 byte return address = 48 bytes. After the call into NoParams, RSP will be 48 bytes further up the stack than it was in the beginning of main.  NoParams is a leaf function, so it doesn’t even bother creating a stack frame.

 

Optional Optimizations

 

Smart Use of the Home Space

If you turn on the optimization flags, the structure of the stack frame will look the same.  The most important thing the optimizer will change is that a function might use its own home space for local variables and non-volatile register storage instead of saving the parameter passing register values.  In the eyes of the optimizer, it’s 32 bytes of space that’s always there.  It doesn’t even have to worry about cleaning it up.  A great man once said, “can’t someone else do it?”

 

Frame Pointer Omission

When MSVC determines that a frame pointer is necessary, you can’t get rid of it.  You can’t make it use a frame pointer, either.  MSVC disregards your FPO optimization settings.  GCC will also disregard your plea to remove it, but will add frame pointers to every function if you tell it to.  I haven’t seen GCC use a frame pointer on its own unless you allocate from the stack.

 

Tail Calls

If the very last thing a function does is call another function, that call is referred to as a tail call.  When the tail call returns, the calling function would only need to run its epilogue.  Because the stack is structured so rigidly, an x64 compiler can take advantage of tail calls and make an optimization called tail call elimination more often than x86 compilers.  Let’s change our previous example code a bit to see how it does that.

Please ignore the fact that the array is not initialized.  I’ve only done that to reduce the disassembly we need to look through.

//important compiler options: /O2 /Ob0 /GS- /Gy- /GL-
 
  #include <stdio.h>
 
  
 
  __int64 g = 0;
 
  void NoParams()
 
  {
 
    ++g;
 
    printf( "%I64d", g );
 
  }
 
   
 
  void Shim()
 
  {
 
    volatile __int64 space[5];
 
     g = space[4];
 
     NoParams();
 
  }
 
   
 
  int main()
 
  {
 
    Shim();
 
    return 0;
 
  }

The disassembly:

NoParams: 
 
    mov    rdx,qword ptr [g]
 
    lea    rcx,[string "%I64d"]
 
    inc    rdx
 
    mov    qword ptr [g],rdx
 
    jmp    qword ptr [__imp_printf]
 
   
 
  Shim:
 
    sub    rsp,58h
 
    mov    rax,qword ptr [rsp+40h]
 
    inc    qword ptr [g],eax
 
    add    rsp,58h
 
    jmp    NoParams
 
   
 
  main:
 
    sub    rsp,28h
 
    call   Shim
 
    xor    eax,eax
 
    add    rsp,28h
 
    ret

Let’s focus on the Shim function: the call into NoParams was changed to a jump, and Shim cleans up its stack frame before the jump.  How does this not break the promise of home space for NoParams?  Think about where RSP will wind up.  It’s going to be in the same spot as it was at the start of Shim, and it will point to the return address that will take us back into main.  There’s also 32 bytes on the stack below RSP for Shim’s homes pace.  NoParams can reuse that for its own home space.  It’s as if Shim never even existed.  Ta da…a nifty little magic trick!

NoParams takes this “I wasn’t here” trick to the next level.  Not only does it jump to printf, it forgoes creation of its own stack frame entirely.  I’ve only seen this happen when tail call elimination is used.  For example: if you move the “++g” after the call to printf, tail call elimination cannot happen and NoParams will create a stack frame.

So long as the number of parameters for the tail call are less than or equal to the calling function’s, then this optimization can be used.  Destructors don’t mess this up either, though the tail call will wind up being one of the destructors rather than the function you typed at the end.  The compiler needs to keep function order the same, and the destructors are guaranteed to come last.

Tail call elimination is a wonderful optimization!  The downside is that function that makes the tail call won’t show up in the callstack.  Since there’s no return address into it, a debugger has no idea it was called.  If you see a missing call, don’t suspect the callstack is corrupt.  Double check your calls and you’ll probably find a call to the function that isn’t showing up in your callstack.

 

Go forth and compile!

I encourage you to experiment on your own to see how the compiler makes use of the stack frame.  Try different data types, including structs.  Watching it move blocks of data around with SSE instructions is kind of fun, and there are some interesting patterns in the way it chooses which variable goes where on the stack.  Stepping through optimized x64 disassembly is almost soothing compared to doing the same with x86 disassembly.  Data flows from the stack to registers and back so smoothly, and it’s always easy to find your footing with a stable, unmoving RSP register.  If you find any particularly cases where the compiler does some interesting things, let me know!

Speaker Highlight – Dustin Clingman

Original Author: AltDevConf

Dustin Clingman is the first speaker we want to introduce you to. We’re very pleased to have Dustin as a speaker at the AltDev Student Summit, which you can now register for right now! Mark your diaries for November 10th/11th and come hear Dustin talk to you about “Managing Up”.

You’ve got the skills and have landed the job. You have the intention to conquer the world…then you meet your manager. No one will ever teach you how prepare you for life within a corporate entity. No matter the size or the sector, every student needs to know how to “Manage Up”.

And here’s some more info about Dustin.

A 14 year veteran of the Game Industry, Dustin has developed games for nearly every mobile platform. In 2002 he founded Zeitgeist Games, which was acquired in late 2008 by IMI Labs and relaunched as ZeeGee Games to focus on the growing Social Games market. In 2012 he founded his newest Label, First5 Games to focus on creating games with the core mantra that they “Be understood in 5 Seconds and Loved in 5 minutes or less!” Presently, he is the Chairman of the Board of Directors of the International Game Developers Association and a Lifetime member of the IGDA.

 

Dustin is just one of the great speakers we have lined up as part of the AltDev Student Summit. Check out the rest of the event, and make sure to register through Eventbrite and join us November 10th and 11th.

Unity Technologies Sponsors AltDev Student Showcase

Original Author: AltDevConf

Last week we announced that as part of the AltDev Student Summit we would be holding a competition for students called the AltDev Student Showcase, in which students could pitch their current projects to a panel of industry veterans in order receive critique and advice on the direction they were taking. The veterans would then pick a winner in the Dragon’s Den style, by choosing how much play-money they would be willing to invest.

But what’s a competition without prizes!?

Unity Logo

We are delighted to anounce that Unity Technologies have kindly agreed to sponsor the event by providing a grand prize for each day of the competition of a Unity Pro license, which will hopefully help students be better able to see their projects completion. We thank Unity for their support, and hope you’ll check out their game development tools.

You are still able to submit your project for consideration to be a part of the AltDev Student Showcase by filling in this form, the deadline is October 13th.

Kickstarter campign isn’t looking so hot?

Original Author: Jason-Swearingen

This is a guest posting by Eddie, Novaleaf’s Game Dev Lead

Kickstarter campaign isn’t looking so hot? Well, dang it.

Well, that’s currently what’s happening to our Kickstarter campaign, God of Puzzle. A couple of weeks ago, I wrote about what you need to know if you’re planning to start a Kickstarter campaign. This time, let’s talk about when your campaign doesn’t go as planned.

What did we do?

So, first thing that happened after your project is launched is that you’ll get a little traffic from people who goes into the “Recently Launched” page on Kickstarter website. This initial traffic gave us 1 or 2 backers. After that initial traffic, you’re on your own.

So, what’s next? Here’re a few things that we tried after our launch:

  1. We started posting in gaming forums and communities. We post to a few places a day, so we could adjust the message to see if we can get better reactions the next day. This include sites such as Reddit as well.
  2. We sent email with press-kit to gaming news sites and bloggers.
  3. Team members spread the words about the game on their facebook and twitter.

So, what happened?

After a week of spreading the words about the project to almost every place we could think of, almost nothing happened. So, we’ve stopped working on promoting the page because we weren’t doing it right, and it’s a waste of time. Instead we decided refocus our man power into figuring out what went wrong and are taking actions to fix it while there’s still time left before our deadline. The rest of this article is information on what we’ve learned from our own experience trying to breath life into our dying Kickstarter campaign.

Let’s first look at some stats. Kickstarter doesn’t tell you exactly how many people visited your project page. But it does tells you how many times your pitch video has been played, and how many percentage of people that click play watch the video all the way to completion.

We were actively spreading the words about our project for about one week, and we’d get around 80-100 views a day on the video. At the end of week one, we got approximately 650 views on the video with about 20% of them played to completion. At this point, the total number of backers is 18. Scary, right? Very; especially when you know that you need at least 500 backers to be anywhere near your funding goal.

So, what that information, this is the list of things that we’ve learned:

1. Some project is a hard-sell for Kickstarter

Not matter how well you construct your pitch, there’s a chance that your project is still a hard-sell for the Kickstarter crowd. Now, I’m not saying that our pitch is perfect, but we do realize that our target market is pretty niche; maybe a bit too niche for Kickstarter…

According to the stats on our project, out of 600-700 people who viewed the pitch video, less than 20 people are willing to back the project. So, that means, for the people that we’ve showed the project to (mostly hardcore gamers in online communities), our project has 2-3% chance of landing a backer. Which means, for us to get 500 backers, we need 20k views on the pitch video. I have no idea if this number is low or high compared to other projects, but it’d be great if the project only need 2000 views to get 500 backers, right?

So, how do you know if your project will appeal to the Kickstarter crowd? Well, this is a good question, and a tough one to answer. But I can tell you that there are two types of projects that have higher chance of success: projects that already have a large fan base and projects that truly innovate. Unfortunately for us, we failed to show innovation in our pitch and the fan base our project (Puzzle Fighter fans) are not as big as we’d hoped.

2. Forum marketing is very tricky

Before I explain why forum marketing is tricky, let’s look some stats related to forum marketing. And before I continue, I should also say that we did not use any Guerilla Marketing or sophisticated marketing techniques; so teams that are doing more sophisticated marketing stuff are probably going to get different results.

For one week, we’ve posted to about 10 different relatively big gaming forums. Each thread that we started would get around 30-100 views (i.e. people that actually click on the topic to view the content). Almost all the thread have zero or very minimal reply. For everyday that I post on forums, the next day we’d get ~80 views on the video, and anywhere from zero to a few backers. So, a lot of the views on the video is probably coming from our forum marketing, but we’re still way off. To get 500 backers in 30 days, we need at least 17 backers a day, not zero to a few.

So here’s why I think that forum marketing is tricky:

  1. Your topic must make people curious enough to click it. Otherwise, not a lot of people is going to see your message.
  2. Your topic must generate discussions. If your topic doesn’t generate discussions, your thread is going to fall off the front page within one or two day for a relatively active forum.
  3. Your message must make people want to click the link to your project page. Otherwise, you’ll get no action in your project page.

After learning the points above, it became obvious to me that starting a thread to directly ask people to “check out our Kickstarter page” may not be effective enough to get 500 backers.

3. Making your project viral is everything

Your project is “viral” when it effectively promote itself. It’s when you can stop promoting your project because other people are already talking about it everywhere. Basically, if the number of backers for your project grows at the rate that you need, without you having to do anymore marketing, congratulation, your project is viral, and probably awesome.

Unfortunately for us, this never happens. As soon as we stop actively promoting the project, we got absolutely nothing. And because our project isn’t viral, it means that if we want 500 backers, we have to find ways to get them all by ourselves, which isn’t easy, especially if you didn’t plan it in advance.

4. Strengthen your social network and research how to do it right

If you’re at all counting on the power of your social network to save the day, make sure that your social network is a strong one and that you know how to effectively promote on social networks. If you think about the “reach” of your initial post and the chance that your followers/subscribers will share or retweet your post, you can probably estimate how many people is going see your post. But out of everyone that saw your post, how many of them actually click on the link? Your post might just be a short sentence plus an image, but it has to do so much. It has to capture the attention of people who are scrolling through hundreds of news feed, stop them from scrolling past it, and click on the link. There are a lot more to social network marketing, so some research in this area will probably help.

What we’re doing to fix it

For our project, we have one last round of ammunition left, and we’ve been trying to make sure it’ll hit the target. This last shot have to be something interesting enough for people to share and make the project more “viral”. This last shot is our playable demo.

It’s still pretty rough, but we’ve been trying to make sure that it’ll leave a good impression on the people who played it. We’re also revisiting all of our marketing plan, as we didn’t really do it right the first time.

Yes, you could say that it is a long shot, but we got to at least try everything before we admit defeat, right! Oh and a little miracle would help too, I guess…

 

 

The Elements of Comment Style

Original Author: Ted Spence

Programming comments are a critical, and often overlooked, part of the development process. Comments may not be exciting enough to have certifications and training classes dedicated to them, but in many ways the difference between a good codebase and an excellent codebase can come down to the quality of the comments.

Comments increase the value of your code. Compared to comments, though, we often spend more time learning methodologies like Scrum and Agile; functional and object oriented programming; test driven development and refactoring.

Yet comments are critical in ways that methodologies aren’t. In the real world, we rarely spend years working on the same project; we often switch from one program to another multiple times in a week! Each program has its own style, design patterns, and idiosyncracies; comments help us learn them. Each team has its own philosophy, development lifecycle, shared knowledge, and communication style; comments help us make progress even if senior engineers aren’t available to explain something.

Comments vary widely. Unless you have interned for me, I’m pretty sure your style of comments doesn’t match mine. Better known programmers than myself have written about comments, including perhaps most famously Donald Knuth’s argument against them. It’s always worth reading about what other people think: we become better programmers, whether we use another person’s ideas or not, simply by knowing about them and understanding their reasons.

The Value of Comments

The primary value of comments is their ability to teach us about our codebase. This kind of shared knowledge helps us avoid bugs that previous programmers anticipated. It helps us switch from one program to another rapidly. Really good quality comments can reduce the amount of meetings we have – by helping others get answers directly from reading the software rather than scheduling time on your calendar.

But I find the most incredible feature of comments is this: Writing lots of comments makes me think through my code. I embark on a project with the goal of writing one comment for every three lines of code, a level of detail that most people find silly, but a level that I find helps me better explain my software architecture both to myself and to someone reading through my work.

I often hear the objection, “I can’t waste 25% of my time writing comments!” Of course, nobody will force you to write a specific number of comments. But in my experience, I spend only a fraction of my “programming” time actually writing statements; I spend more time staring at an algorithm mentally thinking through its consequences, or deciding to refactor. When I work on code with fewer comments, this “staring” time takes longer. Revisiting an old program with no comments requires me to “re-do” the mental work I did when I looked at it the first time.

That said, let’s thinking about the types of comments we write and how they help us.

Explanatory Comments

Explanations are the most commonly used type of comments. An explanatory comment gives us a “reason” or a “justification” for a particular piece of code. If we write some logic that looks non-obvious, or if we’re doing something that looks at first glance to be wrong or unnecessary, you should add an explanatory comment citing enough information to prove your logic is correct.

Another way in which an explanatory comment can help is illustrating pre-conditions or consequences for your logic. Imagine you’re writing an extremely high performance inner loop function, and you discover that you can save some execution time by assuming a list has already been sorted. Before you make that assumption, write an assertion to verify the sort (put it in a “#ifdef DEBUG”), and write a comment explaining why it helps.

When writing an explanatory comment, you should feel free to write as much text as is required. Sometimes a four or five line comment is necessary to communicate the information to the reader. Don’t stress out about rewriting or polishing the comment; focus on communicating everything that needs to be said.

Here’s an example of an explanatory comment for a very obvious test – checking if a variable is null. But this comment tells us who should have populated the variable (“loaded in ValidationStep”), which could help us track down problems with the object’s configuration. It also says that the variable must be set at this point in the code, and that we can’t just throw an exception for a missing parameter.

 
  //loaded in ValidationStep; if null, then we need to create a new one
 
  if (operationContext.Worksheet == null) {
 
  

Documentation Comments

These comments are generally designed by your language or development environment. Many code editors will automatically provide popup help to a user when they hover their mouse over a function call or code statement; and this type of documentation can be extremely useful as a development and debugging aid.

In many ways, documentation comments are similar to explanatory comments – except that they often use a slightly more formal writing style. When writing documentation, take the time to polish your text, especially for functions that are called often. Shorter text is often better; but don’t eliminate critical information.

This example below is the function header for a CSV output function from my open source CSV library. The text is short and designed to be readable through Visual Studio’s context sensitive help; hopefully with enough detail to answer the obvious questions a user might have when calling this function.

 
  /// <summary>
 
  /// Write the data table to a stream in CSV format
 
  /// </summary>
 
  /// <param name="dt">The data table to write</param>
 
  /// <param name="sw">The stream where the CSV text will be written</param>
 
  /// <param name="save_column_names">True if you wish the first line of the file to have column names</param>
 
  /// <param name="delim">The delimiter (comma, tab, pipe, etc) to separate fields</param>
 
  /// <param name="qual">The text qualifier (double-quote) that encapsulates fields that include delimiters</param>
 
  public static void WriteToStream(this DataTable dt, StreamWriter sw, bool save_column_names, char delim = DEFAULT_DELIMITER, char qual = DEFAULT_QUALIFIER)
 
  

Narrative Comments

Some comments are there to hand-hold the reader through the program’s thought process. Rather than explaining complex logic, the narrative comment is tying together lots of simple logic with a story that helps make the code easy to browse. Narrative comments don’t have lots of detailed technical explanations, but they can be very helpful when you pick up a program for the first time (or return to it after a long absence).

By writing good narrative comments, you can show visually when a function has grown to need refactoring. If your story grows unreadable, often your logic needs to be rethought and simplified. If you write lots and lots of narrative comments explaining boilerplate work, perhaps that overhead can be moved to a shared class or initialization function.

These story-style comments can be very verbose, but they can also help you work in a manner reminiscent of “test-driven development.” Rather than writing your logic first, you can write your comments first – this is why all of my comments come before the code, not the other way around. I write by explaining what I’m going to do, then doing it; and my comments always come with a line before them to make it easy to skim.

For example, here’s a series of “narrative” comments I wrote for a data publishing program. I had snippets that already did most of the heavy lifting and I wanted to refactor it into an automatable program. I started by writing a narrative of how I wanted the program to work; after each of these comments, I left space to fill in with calls to existing snippets of code:

 
  // Did the customer want us to compile the MDB database?
 
  if (BuildMDB) {
 
  
 
      // Next generate SQL statements to update the file
 
  
 
      // Next execute the SQL strings onto the MDB file
 
  }
 
  
 
  // Does the customer want us to deploy the MDB database?
 
  

Blame Comments

We frequently are forced to write code by circumstances we don’t fully understand or business decisions that may seem irrelevant or arbitrary. When we’re forced to fix someone else’s bad logic, or when we receive a trouble ticket to make a requested change, it is helpful to blame someone. Because of this, the difference between a “blame” comment and an “explanatory” comment is that the “blame” comment refers to something outside of the code – maybe a person, a bug number, a business case, or a project design document change.

The blame comment helps a programmer track down an external justification for our logic. If our program does something unexpected or random, and we can’t look into the code to see the reason why, we may need to go to an external source, talk to someone, or find a design doc (why haven’t you posted your design docs on an internal wiki?).

Blaming is not always a negative – in many ways, they can be virtually indistinguishable from a “credit” comment. I would encourage you to write your “blame” comments in a language-neutral fashion: don’t let your anger or frustration seep through, just reference the decision. A future programmer may see your justification and craft a better fix that solves the same problem, or they can go to the right source be able to challenge the decision.

Rich Skorski notes that it’s useful to “blame” someone clearly in the comment, and especially to datestamp the comment. When you either blame or credit someone, that enables people reviewing the code to make decisions on the logic or past experience with the author. In some cases, it can show whether assumptions may have changed since the comment was written, and in other cases, as Bruce Dawson notes, the compiler, language, or toolset may have changed. Labeling the blame allows the reader to determine whether the original assumptions should be revisited.

Some examples of “blame” comments from myself and Bruce Dawson:

 
  DbUtils.CommandTimeOut = 10 * 60; //10 minutes: Ticket #19267: increase timeout to handle large volumes of data
 
  // Work around bug in VC++ 6.0
 
  #pragma optimize(“”, off);
 
  

Wrong Comments

If you write as many comments as I do, you’ll often discover that a comment is incorrect. There are a few different kinds of “wrong,” though. Some comments are wrong because the logic that they explain is flawed. Sometimes the comment is wrong because the business decision used as the source of the logic has been changed since it was written. Other times, the comment is simply mismatched with the code – it doesn’t accurately represent the work the code is doing.

Almost a decade ago, Jeff Atwood wrote a concise article about the problems that lead to comments being wrong or useless – and his guidelines are a good way to learn about how to avoid “wrong” comments.

Still, I find that “wrong” comments can be useful in learning a program. You may want to write a unit test to verify that the code is in fact doing something wrong before you fix it. You can write “blame” comments to attach more detailed justification to the code. Or if the comment writer is simply wrong, you can improve the code’s documentation by fixing the comment.

Wrong comments can be teachable moments too. Imagine that you’re investigating a “wrong” comment, only to discover that the comment is, in fact, correct! Along the way, of course, you probably developed your understanding of a key business process. In this case, you may want to add to the comment, appending your new knowledge to what was already there.

This example below shows a code fragment doing something questionable. The function itself isn’t time sensitive, so there’s no reason for a “sleep” statement. But when you read the comment, you realize why there’s a sleep statement – and this realization should help us fix the function so that the sleep statement isn’t needed!

 
  Thread.Sleep(1001); //because our ack file names are time based, we have to make sure they are unique (by seconds)
 
  

Placeholder Comments

Similar to a “wrong comment” is a placeholder comment, designating something not yet known: when you don’t yet understand something and want to remind the reader of a potential problem. These questions are particularly useful when you’re maintaining an existing program, and you need to start understanding a complex codebase.

When you read through some logic and nearly understand it, it’s worth adding a “placeholder” to indicate what knowledge has yet to be demonstrated. If you don’t know for sure that a condition will be satisfied, or if you need further research to make sure a specific edge case won’t occur, write it in a comment. Some authors find it very useful to label placeholders specifically, with text patterns like “TODO” or “NYI” that one can find easily with a global search.

In this example, the author has decided to expose a member variable, but isn’t certain that the solution is ideal:

 
  // Does it make sense to expose the child objects here if the application needs to retrieve both parent and children?
 
  public IWorksheetBucketCollection Buckets;
 
  

However, I often find myself writing a narrative that includes rhetorical questions. In this case, I know what I’m doing, but my narrative comment is in the form of a question. I do this simply because it’s a more readable way of understanding what condition an “IF” statement tests:

 
  // Does this location have a tax authority?
 
  if (location.TaxAuthorityId > 0) {
 
  

Superfluous Comments

Beyond all these other types of comments lie the completely unnecessary. The purest form of unnecessary comments is the archetypal “add one” comment:

 
  // Add one to X
 
  X = X + 1;
 
  

It’s very hard to defend this kind of comment, but let’s stop for a moment to understand why it’s pointless. First, it’s documenting a task (addition) that is eminently readable; the comment adds no information beyond what is already in the code. Second, the comment does not increase the value of the narrative documentation in the code, since it adds no narrative to the variable.

If either of those two conditions change, the comment might be valuable. If someone was to obscure the increment operation by wrapping it in a subsidiary class whose method name wasn’t obvious, the comment might help you understand the function call without having to step into it.

 
  // This wrapper adds one to X
 
  X = TaskFactory.AdvanceWorkflowStage(X)
 
  

In another situation, perhaps the variable “X” is the thing that needs documenting. If we position this line of code in a location where adding one seems out of place or duplicative, we should ensure that our narrative explains why it was needed. For example, consider this hypothetical comment on a loop where we maintain two parallel counters:

 
  // Filter the database records we retrieved; when displaying, X is the actual rowcount
 
  int X = 0;
 
  for (int i = 0; i < a.length; i++) {
 
      if (!ShouldSkipRow(a[i])) {
 
          PrintRow(a[i]);
 
  
 
          // add one to the displayed rowcount
 
          X = X + 1;
 
      }
 
  }
 
  

But we should all acknowledge that the harm caused by an unnecessary comment is forgettable. If you don’t need to read the comment to understand the code, you can happily overlook it. On the other hand, if you get into the habit of imagining that all your code is obvious, you’ll stop writing comments and the codebase will become less readable.

Summary

We should all strive to write useful comments in a way that improves our programs. Yet, swear-word-filled-gem (not safe for work, in some workplaces): a series of comments so noxious the programmer who wrote it had to issue a full explanation.

How is your code commented?

Our Self-Publishing PC Adventure, Part 1

Original Author: Aaron San Filippo

[The Indie Survival Button in all its glory]

(This was originally posted on Flippfly.com)

When we started Flippfly as a company, our thoughts were mostly on IOS: The developer ecosystem is thriving, the barrier to entry is super low, the hardware is awesome, and there are millions upon millions of potential customers. But through our experience with our first release, Monkey Drum, we came to realize a few things:

1. It’s really hard to build a community around an app – and this is one of the things that’s important to us.

2. The landscape is really changing – free-to-play rules the roost, and this isn’t a model we want to focus our efforts on.

3. The PC platform seems much more in-line with our long-term goals and values, and there is a thriving ecosystem here that’s more than big enough to support a small developer like us.

So we decided that, starting with our first major game release, pre-orders on our website for the game, and I thought it’d be useful to share our experiences as we go.

We knew that self-publishing would come with some advantages, and challenges:

AdvantageWe get a bigger cut of the revenues than we do on IOS (more on this later)
Advantage: We have direct contact with every customer who buys a product, and can communicate our future products directly to them.
Advantage: When someone buys one of our products, our Flippfly branding is front-and-center, and we can funnel them into our community forums to make them feel like they’re part of something bigger.
AdvantageWe can publish updates as often, and as instantly, as we want.
AdvantageWe can play by our own rules as far as what’s a passable product, how we handle payment, how our games can talk to each other, what we can link to, etc.

ChallengeVisibility is completely up to us (but we actually like it  this way!)
Challengewe need our own e-commerce setup, and it has to be easy to use, both for us and our customers.

Challenge #1: Visibility

 

This seems to be the biggest one by far. We’re not a well-established developer of PC games (even though I spent 7 years in AAA before this venture) and our only published product as a company so far is a children’s educational music toy for iOS, so there really isn’t a crossover audience there.

Here are some of the strategies we’ve used so far to attempt to get some eyes on us and our game during its development phase:

Development updates and social media participation.

We’ve posted weekly development logs pretty much since we started the project, and then we tweet these, post them to facebook, and occasionally link them from forums around the web.

This hasn’t exactly lit the site on fire with traffic – but it’s kept us on track to make a solid weekly build, and we’ve gotten some very valuable feedback from the few people who do trickle in to play.

I’ve also made an effort to tweet screenshots with the #screenshotsaturday tag, which are automatically posted on ScreenshotSaturday.com – free visibility!

Steam Greenlight page

 When Steam announced that their new Greenlight service was live, we quickly put together some screenshots and a rough video, and got a page up the first day. This had the benefit of getting lots of eyes on the game. Although our goal is self-publishing, we’re certainly love to be on Steam as well.

Admittedly, our presentation here is pretty rough, and we could’ve done a better job of preparing. The initial set of comments were brutal. Most of the posters seemed to think it’s a Flash game, and many suggested we should be making this as an app, not a Steam game. But we saw this experience as a huge positive: It’s a great way to get un-biased reactions from typical Steam users. Getting straight-talk about what people think about your game is harder than you think, especially when they’re friends and family, or well-wishers who come by our website!

Through this feedback, we decided to make some changes to the visual style, and go for a more unique grayscale pallete with some post process that perhaps makes it stand out from the “app” look people were criticizing us for. When we posted some new screenshots, we saw a near instant change in the tone of many of the comments, and the number of favorites increased as well. All in all, this is the type of iteration we like to see happen!

The game concept itself

There have been a few very influential articles for us. One of them in particular is this gem by Tadhg Kelly called making an excellent game. But, it should also be a game that that surprises and delights people in ways they haven’t seen before.

This was useful to come to grips with, because it encouraged us go back to the drawing board a bit, and come up with a single idea for the game related to social/multiplayer, that we feel will make it stand out in a unique way, and that really reenergized us to finish the game. We haven’t announced this feature yet, but I’ll follow up on it in a future post with more details! We’re definitely still learning about how to interact with the press and time our announcements for the best effect.

Playable “Alpha Demo” on Kongregate.com

From the beginning, we started posting Unity web builds of the game on our blog. Our thinking was that the early feedback would help improve the game, and maybe we’d create a bit of a buzz.

And now that we’ve developed the game to a point where we feel it’s fairly fun and “feature complete” in its most basic form, we put up what we call an “Alpha Demo” on the web portal Kongregate.com.
This version has about an hour worth of player objectives and unlocks, and a fairly clear message that there’s a “full version” available. It includes links to our website where people can pre-order, and asks users after a few rounds of play if they’d like to sign up to the mailing list for future updates on the game.

Our early opinion is that this was a good move:  the game has had around 4500 plays as of this writing, and currently sits at a 3.70 rating. The comments have been mostly positive and constructive, with a few people that obviously love the game. There have been about 15 newsletter sign-ups among the players after just a couple days. This was all a nice reassurance for us that yes, we’re onto something here.

It’s also very refreshing to be able to respond to comments, to thank our users personally, and to upload quick fixes any time we want. This is a world of difference from our experience on Mobile so far.

Additionally, we’re tracking usage statistics anonymously through Google Analytics, and this early testing data is telling us things like:

How many people are playing the game Right Now? (answer: 39)

How many people make it to the first “level up” and to subsequent levels, and how long does each level take them?

How many click the “full version info” button?

How long do they spend in the game on average?

Where are our users coming from geographically?

This is all very useful information for us. Even if we don’t make a single sale from Kongregate users, the ability to fine-tune the first impressions and user flow in the game through an active audience is a luxury that we won’t take for granted.

Our goal is to get the game up into the 4.0+ range, and we feel we have a plan and the tools to do that.

Visibility ideas

Beyond these plans, we’ve got some ideas we’ve been tossing around:

 Twitter/Facebook integration? Do people do this in standalone PC games?

– User-generated content: this seems a natural way to turn our fans into product evangelists.

– Personal stories: We’ve had some interesting experiences, but haven’t done a lot of “self marketing.” We’re thinking about our personal stories and how to present these to people.

 Cross-marketing: Maybe there are some opportunities to get some visibility from other indie games or sites?

– Traditional marketing spend: Are ads worth it with a $5-$10 PC game? We haven’t done the math on this yet.
– Press Releases: We’ll definitely be connecting with the press as we go.

– Contests etc.

I’ll post a future update with our progress in this area! If anyone has any experiences they’d like to share, we’d love to hear them!

Challenge #2: e-Commerce:

Apple really spoiled us in that we didn’t have to worry at all about product delivery, payment, sales taxes, returns, etc. We just upload our app and set the price, and they send us a check every month.

It turns out, there are lots of solutions for self-publishing that have about the same level of benefits. We chose a company called  customized, secure store page that looks exactly like our Flippfly site, so from the user’s point of view they’ve never really left our site.

Delivery

The only big question we had to deal with was how to deliver the actual product. Since we’re not finished with the game yet, we needed to figure out how we would handle pre-orders.

FastSpring (understandably) doesn’t care for the idea that we’re just going to send a promise of the game when it’s finished. After all, what if we got hit by a bus, or (perhaps more likely) got bored with the game and decided not to finish it?

So we decided that we would send an early build along with the pre-orders, which would be mostly identical to our “alpha demo” but without the “buy the full version” messaging. As we add more content, we’ll send updates to our purchasers, right through the final release.

This raised the question of: How do we get the early product in the hands of our customers, and get them all updates as we go?

Initially, we were looking into the option of creating a key generator scheme, where there would be a public download link, and people would essentially be purchasing a key that they’d enter into the game to activate it.

In the end though, we decided that for now we would just send a totally unlocked early release version to FastSpring for direct customer download, and since we get the email addresses of everyone who’s bought the game, we’ll provide an update mechanism in the future. We’d really like to have a setup like the Humble Bundle store, where you can simply log in and download everything you’ve purchased. I’ll give you an update on this when we figure out exactly how we decide to handle it!

Customer Options

We decided to take a page from Kickstarter, and offer multiple tiers of purchase:

For $5, you  get a copy of the game

For $10, you get a copy of the game, a soundtrack, and custom wallpapers.

We may add more tiers as we go. If we find that some people are really getting into the game, maybe they would like a poster, or a miniature of the player ship, or even a customized controller? Our goal is to respond to what the community wants.

Community Involvement

We’re  very determined to take full advantage of this platform, and involve our community however we can. We setup a Kongregate site.

We may setup a weekly survey and direct people to it from the demo version, and we’ve been considering ways to let our fans contribute content to the game itself. We want the project to have a long lifespan, and we’re determined to encourage this however we can.

Thanks for reading! I hope it was helpful for someone. I’ll post a followup soon with more about our ongoing development, how the preorders are going, and any new challenges and opportunities that come up. In the meantime, why not follow me on Twitter for more updates?

Further reading:
IndieBits – pretty much everything on this site is relevant if you’re thinking of self-publishing.
How To sell your game online without using an app store – from Cliff Harris, developer of Gratuitous Space Battles.
Are You Invisible? [Marketing Stories] – Great food for thought from Tadgh Kelly on making yourself visible.

Head Over Heels: Upper Body Movement In Gameplay

Original Author: Simon-Unger

For every gameplay feature that makes it in, ten were cut so that it could survive. In the epic battle (or collaboration, depending on your team/company) between Designers, Programmers, and Animators to see these features get shipped, some core fundamentals often fall by the wayside. In games animation, it is very common to approach quality of movement in the wrong order; starting from the ground up.

Foot planting, phase matching, complicated IK solutions, procedural layering; they all have their place but we often sacrifice much to keep them working. In film, animators long ago realized that audiences observe characters in a very specific priority order. We start at the eyes, then the head, then the silhouette. Animators work very hard to give the upper body a sense of weight, obey the laws of force, and move in appealing arcs.

When it comes to in-game locomotion, we rarely get to see the eyes clearly as we’re mostly behind our character, so the next stop down the chain of importance is the head. Unfortunately, when we place such a high focus on maintaining solid foot-planting, we create a fulcrum point at the ground and our characters often pivot in extreme ways to compensate. This is especially noticeable in bigger direction changes and when aligning characters to interact with each other (melee, high fives, piggyback rides, etc.).

In reality, the human body pivots around its centre of mass, the mid to lower torso. Through a series of complex mechanisms, humans have evolved the ability to maintain stability in three major areas of the body; the torso (the vestibulospinal reflex), the eyes (the vestibulo-occular reflex), and the head (the vestibulocollic reflex). The fundamental purpose of these mechanisms is to maintain equilibrium as well as visual focus on predators and prey. It’s difficult to run away from a sabre-tooth tiger or catch a shark with your bare hands if your vision is blurry and you keep falling over.

You can see these mechanisms at work in this video. Pay close attention to the head movement of the girl in the green and yellow.

 

 

Her head hardly moves for the entire race! (Side note: this is also fantastic squash and stretch reference, but that’s another article)

Let’s look at another reference video. Again, pay attention to the stillness of the head and centre of gravity on each of the athletes. Draw a mental path that the head is traveling along in space. Even in extreme direction changes, such as the guy falling on the skateboard, the head is held relatively still compared to the other extremities.

 

 

As you can see, especially in the first two clips of the football players doing cone drills, the legs and arms are being used to redirect the inertia of the centre of mass and the head is doing its best to remain as still as possible. On the sharper turns, the entire body almost appears to rotate around the head’s position in space.

As a former Animation Director was fond of telling us, the only animation principle you need to remember is “Force”. You cannot move an object in any direction without force in the opposite direction. The amount of force being applied is how weight is demonstrated. To make a sharp, 90-degree right-hand turn at a running speed, the character needs to decelerate and redirect his mass by applying force towards the front and left sides of his body. We can see this in action when we break down one of the turns in the video.

 

 

The green line represents the path the head is taking throughout the turn. You can see the first application of force on the #1 foot-plant. The right foot is out in front and to the right of the centre of mass to redirect the body. On the #2 foot-plant, the right foot is now behind and to the right of the centre of mass to redirect to the left as well as accelerate the body forward. Notice how throughout the entire turn the body appears to pivot underneath the head to complete the turn.

Taking this reference and knowledge, let’s review some in-game footage from a few random clips I found online.

 

 

Hopefully the issues in the head movement on screen are apparent to you now. These types of issues aren’t exclusive to games either. Often in feature films, especially ones with a mix of live action and CG, the CG character “feel” wrong to the viewer but they just can’t pinpoint the reason why. There’s a good chance that the character is exhibiting some of the issues described above.

Here are a few clips showing fluid head and core movement. Notice how even though some of the movement is almost super-human, it still remains quite believable when this principle is applied.

 

 

So, the next time you sit down to create a movement system, try to keep the above in mind. As we move towards more elaborate motion requirements on the next gen consoles, stepping back and taking stock of the fundamentals will be even more important.

Start with your higher-frequency animations. If you have some kind of metrics system built into your game, data-mining for which animations get played and seen the most should give you an excellent starting point. Usually this means your main character’s core locomotion. Starts, stops, and turns. Try to avoid getting caught in the common trap of spending a lot of time worrying about an area that will be seen less than 20% of the time. Focus on the 80%.

Unfortunately, there is no “magic bullet” to solve all of this currently. Head tracking, IK, animation layers, procedural systems…all need to be authored with this in mind and working together to maintain a sense of weight and force. Often the cause of these issues is multiple animations systems working against each other. Always be asking if each new component is supporting the greater goal: responsive, believable character movement

I would love to hear in the comments about how other teams have approached this and what your challenges and successes were.

Building an HTML5 Game? Don’t Shrug Off Atlases.

Original Author: Colt McAnlis

HTML5 is an amazing technology for designing web sites. The general flexibility of HTML5 markup and JavaScript often leads web developers to create their content using individual image elements. This approach works well for small sites with low overhead, but for games or other high-load websites, using droves of single image elements leads to long load times and slow performance, resulting in a poor end-user experience.  In an ecosystem where 3 seconds may cause you to lose half your users, it’s important to use the proper tool to address this issue: texture atlasing.

GRITS. This single texture holds all the smaller images from the game that contain alpha values. Loading these images in a single texture reduces load time and improves runtime performance.

What is texture atlasing?

In real-time graphics, a texture atlas is a single large image that contains many smaller sub-images, each of which is referenced independently. Texture atlases sprang up with the advent of 3D games, and have been around as long as we’ve had such games (for instance, Quake 2). Atlasing was originally used to accelerate the performance of 3D games, where there is significant overhead when swapping out or referencing new textures during the rasterization stages of a 3D pipeline. By combining all the smaller textures into one larger one, the graphics pipeline incurs less overhead from swapping, resulting in better performance.

A side note on terminology: Many of you fancy HTML5 folks out there might say that a texture atlas is the same thing as a sprite sheet, but I don’t believe that’s correct. A sprite sheet is an atlas that contains only sprites. In contrast, an atlas can contain many charts; each chart is a large image that holds a single type of graphic resource – e.g., sprites (for animation), UI textures (which are not animated), functional notion.

 

The benefits of using atlases in HTML5 games

Using a texture atlas in your HTML5 game can help your game load faster and run faster, and also reduces your bandwidth cost.

Faster HTTP load times

Google I/O talk, a 4k x 4k texture fetched from a server can take around 241ms to download, which is pretty fast. If you were to chop up that single download into 4096 separate requests, at 64×64 pixels each, the total load time changes drastically for the same number of pixels: It would increase from 241 ms to  4.3 seconds, an increase by a factor of 17x. The timing charts below illustrate this difference graphically:



Fetching a 4096×4096 texture from a server requires a single HTTP request, and the request resolves quickly.

Fetching assets individually with multiple HTTP requests takes a long time. The long, lighter-shaded left-hand portion of the duration bars represent time where the browser blocked the connection because too many requests were being issued.

It’s important to understand that there exists an upper limit on the number of requests that a browser can make to a single server. The browser itself sets this upper limit, and when the limit is reached, the browser blocks subsequent requests until an open connection becomes available. This is the primary reason for the performance difference we see with individual assets versus atlased assets. If you have 4,000 pending HTTP requests, and only six connections are available, all the requests get stacked. In the figure above, the lighter-shaded portion of each duration bar is where Chrome blocked, waiting for an active connection to come along.

In addition to reducing overall load time, atlasing also helps reduce the number of HTTP requests from your app. This is a hyper-critical issue that the developers of hard way: During development their app went viral, and their hosting service suspended their account until their request load dropped.

 

Reduced browser runtime overhead

Using individual texture assets can also have a very large impact on your game’s runtime performance.

Web browsers have two main components: a JavaScript VM and a DOM/Layout engine (usually garbage collection process in WebKit can optionally keep the element in memory even though the JavaScript engine no longer needs it. To use the cache properly, WebKit can detect when the system is resource-constrained (i.e., when the amount of available RAM is low), and instantiate a cache-eviction process to remove unneeded resources in an effort to improve performance. For applications with a small number of DOM elements, the cache-eviction process is generally not an issue, but it can become a problem as the number of cacheable objects increases and the garbage collection algorithm spends more time looking for dead objects to reclaim. For 2D, image-based games this can be a considerable problem, e.g.,  when 2,000+ animated sprites and background textures are loaded and referenced individually in a browser. For these apps, images are generally the biggest offenders, and atlasing can really help:  By combining the individual images into larger atlases, the number of unique cacheable resources decreases, allowing WebKit to spend less time in its cache-eviction process in resource-constrained environments.

(To be clear, the WebKit in-memory caching behavior described here has nothing to do with the JavaScript garbage collection algorithm and the problems you can get from incorrectly managing JavaScript objects.)

 

Reduced GPU overhead

In Chrome, the 2D canvas element on a page has access to hardware acceleration if it’s available. That means all of your draws, images, and transforms are handled by the GPU, which significantly improves performance. The catch, however, is that there are a few abstraction layers between your API calls and what the hardware is doing.

It’s been known for quite some time that NVIDIA GPU Programming Guide (pdf)). Working with a hardware-accelerated canvas is no different. Each texture must be bound to the GPU before the primitive quad can be drawn, and with a limited number of texture slots for a given GPU, there’s quite a bit of time spent swapping textures in and out of the proper sampling units. Atlasing reduces this overhead by allowing the GPU to bind a single texture (or a smaller number of textures) to the graphics driver, eliminating the extra overhead of the swap.

 

Reduced Memory footprint

With the exception of dumping the pixel data directly (ie, a DirectX implementations of compressed textures, has a general overhead of 128 bytes for the header, which may not seem huge when compared to the data within it; However consider that 2000 loose texture files (not uncommon for a AAA game) would incur an extra overhead of 250k that needs to be transferred across the wire for each user loading your game. Packing these textures into a single atlas removes the redundant overhead of these header bytes, reducing the overall size of your program.

 

Packing charts into an atlas

Creating a texture atlas is a tricky engineering task. Texture packing is a type of NP-hard. The problem is so challenging that I frequently use a variant of this algorithm as an interview question to evaluate the skills of potential hires.

TexturePacker is a great off-the-shelf tool that fits into most content pipelines quickly; it will generate the atlas data given a list of textures, alongside a data file that maps the individual source images to their final locations in the atlas.

If you’re going to roll your own texture packer, I suggest you begin with some research. Here are some great places to start:

If you’re looking to do highly complex packing (e.g., font glyph packing), most font rasterization libraries come with very aggressive atlas packers. Rectangle Bin Pack algorithm.

Once your data has been packed into charts, you’ll also need to output a mapping file that lists where each leaf-image (individual image) is in the atlas.

Using atlases in your game

Use of atlases in HTML5 games varies by game type:

  • A pure DOM game can use a CSS sprite sheet, and set CSS properties on a DOM image after loading the atlas data file.
  • A canvas game can use the canvas.drawImage API, specifying a subsection of an image to be drawn to the canvas location.
  • A modify the UV-Coordinates of a vertex to reference a subsection of a larger image using normalized floating point values.

Some perspective on game development in HTML5

Web browsers are amazing programs: They abstract out the underlying complexities of loading and rendering web pages, hiding the under-the-hood machinery from the average web developer. For high-performance web games, however, this is less than ideal. The layers of abstraction make it generally unclear how to organize data for maximum performance, and can lead to increased overhead. As with most development platforms, the key to high performance is a thoughtful understanding of what’s really going on, and knowing what tools are available to aid in developing real-time applications.

Stepping back a bit, it’s clear that HTML5 games have great promise. The ability to iterate quickly and deploy content across the Internet is a powerful incentive for developers. But it’s important to approach HTML5 game development with the proper perspective. Regardless of the unicorn dust of the web, working in HTML5 has many of the same pitfalls as console, mobile, and desktop development. Game developers need to continually explore and find great solutions for difficult problems.

For a take on HTML5 game development from the point of view of a traditional game developer, take a look at the following videos:

A Data-Oriented, Data-Driven System for Vector Fields – Part 1

Original Author: Niklas Frykholm

A vector field is a function that assigns a vector value to each point in 3D space. Vector fields can be used to represent things like wind (the vector field specifies the wind velocity at each point in space), water, magnetism, etc.

To me, wind is the most interesting use case. I want a system that can be used for physics (trees, tumble weed, paper cups), particles (leaves, sparks, smoke) and graphics (grass). I also want the system to be capable of handling both global effects (wind blowing through the entire level) and local effects (explosions, air vents, landing helicopters, rising hot air from fires, etc). But I don’t want to limit the system to only handling wind. I imagine that once the system is in place, it could be put to other interesting uses as well.

There are a number of things that make this an interesting non-trivial design challenge:

  • Vector fields represent a global shared state. All systems (particles, physics, etc) should react to the same wind. This can create strong couplings between unrelated systems, which we want to avoid.

  • The system must be fast. We want to be able to make large particle effects that are affected by wind. As a design goal, let’s say that it should be able to handle at least 10 000 queries / frame.

  • As stated above, the system must be flexible enough to handle both global wind and a large variety of different local effects (air vents, fans, etc).

I’ll outline the system in a series of articles. Let’s start by thinking a bit about how we can represent the vector field in a way that allows for fast queries.

1. Use a functional representation

Storing the vector value for every point in 3D space at a decent resolution would require huge amounts of memory. It would also be very expensive to update. If we wanted to change the global wind direction, we would have to loop over all those points and change the value.

So, instead, we will use a functional representation. We will express the field as some closed function F(p, t) that gives us the field vector at point p in space at the time t.

For example, we could express a global wind that oscillates in the x-direction as:

F(p, t) = Vector3(sin(t), 0, 0)

The closed function form allows us to evaluate the vector field at any point in space and time.

Note that even with a functional form as the main representation, we can still interact with grid based representations. For example, we can render some section of the F(p, t) function to a texture for use on a GPU. Similarly, if we have some grid based wind data that we want to add to the simulation, we could use that as part of the F(p, t) expression:

F(p, t) = Vector3(sin(t), 0, 0) + sample_grid(grid, p)

2. Ignore the time coordinate

The vector field function F(p, t) is a function of both space and time. The wind varies throughout the level and if we look at any one point, the wind at that point varies over time.

But in practice, we treat the p and t coordinates very differently. We start at some time t_0 and then evaluate F(p, t_0) for thousands of different p values. Then we move on to t_1 and do the same thing.

We can make use of the fact that t remains constant for a large number of evaluations to simplify the function. For example at t=0.5 the function:

F(p, t) = sin(p.x) * sin(p.y) * cos(t)

simplifies to:

G(p) = sin(p.x) * sin(p.y) * 0.8776

which is cheaper to evaluate.

Taking this approach a step further, it makes sense to split our system in two parts — a high level system that knows about time and every frame produces a new G(p) for the current time, and a low level system that ignores time completely and just computes G(p). Since the high level system only runs once per frame it can afford to do all kinds of complicated but interesting stuff, like constant folding, optimization, etc.

For the low level system we have reduced the problem to evaluating G(p).

3. Express the field as a superposition of individual effects

To make it possible for the field to contain both global effects (world wind) and local effects (air vents, explosions) we express it as a superposition of individual effect functions:

G(p) = G_1(p) + G_2(p) + ... + G_n(p)

Here G_i(p) represents each individual effect. A base wind could be expressed as just a constant:

G_0(p) = Vector3(2.1, 1.4, 0)

A turbulence function could add a random component

G_1(p) = turbulence(seed, p, 4)

An explosion effect could create a wind with a speed of 100 m/s outwards from the center of the explosion in a sphere with radius 4.0 meter around the explosion center:

G_2(p) = sphere(p,c,4) * normalize(p-c) * 100

Here sphere(p,c,4) is a spherical support function that defines the range of the effect. It is 1 if ||p – c|| <= 4.0 and 0 otherwise.

Note again that we have stripped out the time component. At the higher level, this might be an expanding sphere with decreasing wind speeds, but at the low level we only care what it looks like at this instance.

Similar functions can be added for other local effects.

4. Use the AABB to cull local fields

If we have a lot of local effects (explosions, etc), evaluating G(p) will be pretty expensive.

We can reduce the cost by only evaluating the local effects that are close enough to our particle system to matter.

I.e., instead of evaluating G(p) for all particles, we first intersect the AABB of each G_i(p)‘s support with the AABB of our particle system.

That gives us a simpler function G’(p) that we can then evaluate for each particle.

If we wanted to, we could use the wavelength of the field for further simplifications. If the scale at which a field effect changes is much larger than our AABB, we can replace that effect with a Taylor series expansion. Similarly, if an effect oscillates at a scale much smaller than the size of our particles, we can replace it with its average value.

Next time

Next time I will look at how we can efficiently evaluate arbitrary functions, such as:

G(p) = Vector3(1,1,0) + turbulence(seed, p, 2) + sphere(p, c, 4)

for a huge number of particle positions p.

This has also been posted to The Bitsquid blog.