Gaming Your Way

May contain nuts.

Outpost 2 title animation

Isn't it great when you can just be lazy and link to someone else's blog ?

Construction of the title animation.

Lux has done a great write up of all the steps which go into making the Outpost title screens just so insanely lovely. Maybe one for the artists out there rather than the coders, but getting an insight into good design is always important for everyone.

Squize.

HaXe, NME and I

Start of the week I had a play with HaXe / NME, I figured it was more than worth a day or two to play with them.

It was a mixed bag to be honest. I use FDT as I'm a Mac boy ( Plus I just like Eclipse, I don't understand the hate for it ), and they've really improved HaXe integration in it, but, HaXe and NME are different beasts, and the support for NME isn't as good. I did find a handy ant script for it, but... it may sound petty but it's a bit of a workflow breaker. Not a huge deal having to run an ant script, and I'm sure there would be someway to add it to the launcher chain which someone smarter than me could figure out, but screwing with my workflow really bugs me, and these simple little changes soon become an annoying chore. I don't want development to have more steps than it had before, that's the opposite of progress.

I'd read mono-develop was good with NME, and as Unity uses that and I'm looking ahead slightly, I thought I'd give that a go. Sometimes its better to start afresh rather than shoe horn things into your current setup. It's, well, it's ok but it's no FDT. I was missing auto-importing and code completion seemed to be lacking ( Again this could be a learning curve thing, I'm sure some people will read this and be screaming that I'm a dumb arse, it's just a simple key combo of <whatever> ).

So I set about porting O2, I mean it's just Float rather than Number, Int / int and Void / void pretty much. Got as far as my Init class where I call my fpsCounter and arse, first brick wall hit. From what I can tell you can't really included a code laden swc if you're using NME. Time to convert the code over to HaXe, which didn't take too long as there's virtually no code in the fps counter. K, job done, how do I include the assets I need ?

I had it in my head that HaXe supported importing swc's directly now, but the only info I could find was for importing swf's. Being the stubborn dick that I am, and stupidly believing my brain, I lost a load of time trying to find how to import a swc. You can't. K then, lets just import the swf. That was a bit of a struggle as I got my head around it, but at the end of day 1 I had NME set up, mono-develop installed, and 3 classes up and running with a fps counter. Oh.

Day 2 I started adding my Layers class, which required some assets from my huge assets.swc ( swf now ). It seems imported assets have to start with a capital letter ( Something I'd discovered doing the fps counter ), argh, I'm a camel case boy, every single asset export name in every game I've ever done is lower case. It's ok, it's fine, this will pay off when I'm running O2 on mobile at 60fps without stage3D. And now it's saying under mono-develop that it all compiles fine without errors, but there's no swf to run. What now ? ( Also before that I'd seen that my simple little 3k outputted swf was 24k when built with NME, there were some additional classes being shoved in there, but that's not a worry, shit it's only day 2, there's going to be things I don't understand and the community is really lively around NME so nothing to really worry about there )

At this point my spirit was starting to break. I wasn't liking mono-develop, the swf was taking nearly as long to compile as the full blown game using the Flex compiler just by adding the assets in there, and there wasn't a swf to test even at the end of it.

Fuck this. Time to go back to FDT and HaXe, let's get that working, then look at NME after. Ah, FDT I missed you, so much quicker and the build times are stupidly fast. Copied everything back over into the HaXe project and then this line gave me an error,

mapPlayField=new BitmapData((640/32)*7,(640/32)*6,false,0);

Really ? It seems using a division in HaXe casts the number as a Float, but the BitmapData constructor expects an int, which quite rightly threw an error. It makes sense, it's logical, I get it. It needs casting as an Int. But that was the exact moment this camel's back broke. I could either plough on for the rest of the week porting O2 to HaXe, and then hope that runs out of the box with NME, with the performance improvements I'd expect, or call it a day. You can guess which option won.

If this seems critical of haXe / NME, it's not meant to be. They're both as sexy as you like, it's more a combination of things. Losing my workflow, a lack of patience, and just the vast scope of porting a project as huge as O2. I've got an upcoming client project which targets Android ( I may be an indie, but an indie who needs to afford food ) and I'm going to use NME for that, it's a perfect way to test it and I'm glad I've done this ground work, it wasn't two wasted days, but when it comes to porting a large existing project I think it's not feasible until you've got a lot more experience of working with it under your belt.

Squize.

PS. Thanks to all the guys who helped me via Twitter, wow, Team HaXe / NME are like Amiga owners in their love of the platform.

Bye bye Swarm, hello side quests

We have been thinking what we could do with Swarm mode in Outpost 2. I really like the mode, it's just a nice switch off your brain bit of shooting fun, and I think it holds up well on it's own ( Outpost:Swarm turned out much better than I could have hoped ). But, I don't think we integrated it well enough in Outpost:Haven, the idea was to add a little extra to go back to after finishing the story, to give the whole game more value. It does, but it's a little bit disconnected ( To the point that it actually works as a stand alone game with very little story context attached ).

Our thinking with Swarm in O2 was to make them optional "Side quests", kinda. The plan is that even during the game itself you'll be able to select a side quest from the mission select screen and go and have a bit of fun there before coming back to the story mode. Going down that path meant what do we reward the player with for doing a side quest ? They'll get extra XP which of course helps with unlocking items, but is that enough ? We want to encourage people to play the mode, there's no point adding value if only a small percentage of players are taking advantage of it, so we're going to add unlockable perks as your reward which should make a very real difference to the story mode.

So that's the current plan, anything to make this game even more complicated and hellish to code.

Squize.

PS. Should we release Swarm:Facebook this week ? I can't see why not, so we'll do a soft launch some time this week I guess.

First design faux pas*

If you've played Outpost:Haven you'll know on the first level it's a bit of a mini-tutorial where we have both characters, Lee and Jameson.

Very early on we split them up, Jameson goes and takes a lift and goes off to have all the adventures in Outpost 2. For continuity we're keeping that sequence in O2, except obviously this time you play as Jameson.

So yesterday I started adding the path finding code to the main player class, you hit the invisible trigger, the text comes up "Lee, do your thing here, Jameson get on the lift and have your own adventures" ( Paraphrasing slightly there ) and the pathfinder kicks in and moves you to the lift ready for level 2.

No, sweet baby Jesus, no! In the cold light of day I see how wrong that all was. Was I really going to take control away from the player during the opening minute of the game ? What was I thinking. That was truly awful game design, to take the player out of the game before it's even started. So today I'm ripping out all that badness and doing it properly, and writing a blog post to shame myself so I never do anything that bad again, and to hopefully show how what may seem an ok design choice always needs thinking about.

Squize.

*In Outpost2 that is, there have been dozens and dozens of other design fuck ups over the years.

Dynamic shadows in Outpost 2

This is a freshly added feature, so it may yet be ripped out due to performance concerns, but I thought I'd share anyway.

Sexy big shadows

So we've now got dynamic shadows on the player sprites in the game. We can't do anything with the static wall shadows as that would be just too costly, which is a pity, but I'm hoping we can run it on the larger baddie sprites without the game grinding to a halt ( Since O2 has been basically in pre-production for a week and a half now I've been refactoring a lot of the code, such as the particles, to gain performance which should hopefully enable us to add even more eye candy than in the original ).

Let's get our hands dirty with some theory of how it works.

Ah, light probes

On the map we add some "Light probes", which are our light sources ( The actual light images you see in the game / map are just that, bitmap images, so we had to add specific ones. It does have the advantage of giving us more control though ).

When we plot our level we loop through all the light probes and store their x,y and alpha. Then we do a distance test to the player and sort the array where we store all the light probes based on that, so the very first one closest to our player at the start of the level is at the front of our array.

From there we just check every time the player moves their distance to the light probe. Based on that we can set the length and darkness of their shadow ( So it's a little bit of atan2, and some scaleY / alpha code wise ).

The tricky bit is moving from one probe to another. Originally I just checked the next and previous light probe in the list ( Hence pre-sorting them at the start ), but when there were a few together ( Like in the example above ) that could break, which wasn't part of the plan. So I've just altered it that on even frames we check the 5 probes "behind" the current one in the array, and then odd frames we look 5 in front ( The check is just a simple distance check, if the probe we're testing is closer to the player than the current one, then make that the current one ). That seems to have fixed things, although it needs testing on a complex level, which is why it may still yet be ripped out.

The first approach wasn't a dead loss, it's much quicker than the current one as we're only checking against 2 probes, so I've kept that code for the npc and it'll be what I use for the baddies, as I think we should be able to get away with it.

As a final touch the shadow is animated, it's actually a walk cycle from our Knight's Quest game, but with scaling / blurring and alpha you couldn't ever tell. Speaking of alpha, the reason we store each light probes alpha property is because that sets the intensity of the light source, with full 100% alpha being the brightest possible light sources. I'm toying with adding colour information to them too ( It'd be so easy if we could just add a tint and read that, but unfortunately not ), as it would be cool if for example when you're approaching a console the screen would not only let the player cast a shadow but light him up too ( It would make them similar to their Unity Light Probe namesakes ).

There are limitations to this, we're only ever running one shadow sprite as opposed to 4, so in the in-game grab above the sprites should be casting shadows from the other 2 light sources too, but this is just meant to be a bit of subtle eye-candy so there's only so much cpu cost we can spend on them. I'm sure someone on Kongregate will let us know about it anyway.

And that's basically it, hopefully it'll make the cut as it does look cool.

Squize.

Just a quick one...

I do love it when a bug does something you could never code in a million years, with the added bonus of it looking pretty.

Perhaps not the best way to show a first glimpse of the new game ( Quantic Velocity ) but we're drowning in work, so this is all we've got right now.

Squize.

So how does the NPC AI in Outpost:Swarm work ?

Now Outpost:Swarm is live I thought it may be an idea to explain how I did your in-game partners AI.

If you've ever read up on Boids you'll know they have 3 simple rules,

Separation

Alignment

Cohesion

And all the examples you'll see are bird like objects flying around, maybe towards your mouse pointer, maybe avoiding obstacles. All seems simple enough. Adding them to a real game however quite a bit trickier.

For separation we have to ensure the NPC is avoiding both the player and all the baddies. Firstly we find the distance to the players sprite using a simple

distance=dx*dx + dy*dy;

Like you would in your usual circle to circle tests. If we're too close then we need to repel the NPC from the player, via:

tmpPoint1.x+=dx+dx;

tmpPoint1.y+=dy+dy;


Where tmpPoint1 is just a new Point(0,0);

That's part 1 of the test done, the second is checking against all the baddies, and there can be a load at any one time. What I did was use a flip flop, every even frame we get a list of all the possible neighbours ( Baddies which are close enough to care about, if they're on the other side of the screen then we can skip them ), every odd frame we do exactly the same distance check as we did above.


Finally we divide our Point value,


tmpPoint1.x/=speedDivisor;

tmpPoint1.y/=speedDivisor;

( private var speedDivisor:Number=20; )

 

This keeps the values within a respectable range so we don't move too fast.

Outpost:Swarm

The next rule is alignment. Lucky for us we don't care about that in this case, we're not creating a flock of birds or swarm of insects, we just want one guy to look fairly smart and follow his friend around.

Cohesion in this case means following. We do another distance check to the player, but this time with a greater radius ( We want them close and for the NPC not to lose sight of the player, but we don't want them virtually kissing. That's planned for the sequel, Outpost:Date&Fuck ).

var dx:Number=bodyXPos-targetX;

var dy:Number=bodyYPos-targetY;

var distance:Number=dx*dx + dy*dy;

if(distance<3000){

  tmpPoint2.x=tmpPoint2.y=0;

  return tmpPoint2;

}

 

tmpPoint2.x=(targetX-bodyXPos)/speedDivisor;

tmpPoint2.y=(targetY-bodyYPos)/speedDivisor;


Note the use of targetX/Y, rather than PlayerX/Y, we'll come back to that at the end of my presentation. As you can see, it's pretty much the same thing as before, and something I'm sure most of you have done with your circle to circle checks.


Right, we've got two Points after running our rules, time to calculate the NPC's velocity.


velocity.x=rule1V.x+rule2V.x;

velocity.y=rule1V.y+rule2V.y;


Then we do a quick test to make sure the velocity in both directions isn't greater than the max speed we've set for the NPC, we don't want him outrunning the player ( Or actually, not to outrun the player enough that people will notice ).

The next part was the tricky one, we can move him around fine, but what about the walls ? It turned out to be surprisingly simple. We use good ol' tile based checks. If there's a wall on the horizontal of the NPC we set velocity.x=0; and then the same with the y. 

We're finally there, we just finish off with

sprite.x+=velocity.x;

sprite.y+=velocity.y;


Cool, and that's how you can use Boids in real life ( The same principle handles the baddie movement ).
 
Let's test that out in game. Excellent it works, and if I manage to lose the NPC behind a wall then... oh tits, he'll just sit there. That's not a great look for a hard as nails space guy with a big ass gun.
 
Check this level map out,  

AI path

Within each level we lay down a path for the AI. Every couple of frames we look to see if the NPC can "see" the player using a line of sight. If he can't it means we've ditched him behind a wall.
When that happens we fire out 4 rays from the NPC until it hits one of those path tiles ( Remember at the heart of the game is a tile engine running alongside the purely physics based one ). Once we've done that we can easily find out which is the nearest part of the path, we change the TargetX/Y ( From above ) to our tile and the same code that moves him towards the player moves him towards the path.
All the time we're moving towards the path we're doing our line of sight checks to the player, if we spot him again we break off from the path and go back to following the player.
 
It's not fool proof, if he gets lost then he's only going to make his way to the path and then not do anything really clever, but because the levels are small enough you should soon bump into him again to get him following the player. Also, he doesn't really need to be that smart when he's off on his own, we just want to create the illusion that he's not a dumb arse, he doesn't need to be Stephen Hawking ( Perhaps not the best example when talking about movement ). Finally, we're still using Flash, we don't have all the CPU time in the world to do something really fantastic.
 
And that's how we move the NPC.
 
Squize.
 
PS. Wow, looks like I've got about 40 fonts / sizes in this, nasty, but it took enough time to write this up, I'm going to swallow it looking slightly ugly.

Week whatever

We're getting there.

New in from last time are Perks. These are as you'd expect, unlocked at a certain rank and there are 3 available at once from a total of 6. There's nothing really earth shattering about them, it was more a way to justify XP / Challenges ( Which I've still got to do, but can't really face ).

Also we've got more levels in there now, I'm just starting on level 9 ( It's a bit of a slog ), there are some asteroids in the background to go with the planets which add a little something and the save routines have been tidied up a lot.

I'm trying to think what else has gone in there, obviously nothing too astounding otherwise I'd remember it ( I will the second I post this ). Hopefully either tonight or tomorrow I should get some new music and player sprites to go in there which I'm really looking forward to. Ah, pause mode, I think that's new from last week. How grasping at straws am I.

Shall we do a little beta ? If you fancy giving it a go post a comment and I'll hopefully post something up tomorrow ( via email, not the blog ) and then you can let me know I'm deluded and it's not really all that. Cool, it's a date then.

Squize.

Week IV

Another pretty productive week on DN8:Pulse.

Particle orgy

I've managed to get all the player power-ups in there, and today added the first boss ( Which doesn't sound all that, but it meant doing the whole "Warning" text stuff which took a while to design nicely ).

We're currently up to 5 levels done out of 12, which is pretty good going. Also quite a bit of time has been spent on the Android version, the control mode is finally nailed in that now, it plays much better than I'd have hoped and we're not sacrificing too much visually ( Less particles, fewer use of blendModes etc. but in terms of gameplay it's exactly the same ).

I also checked how my phone, HTC Desire S, performs in comparison to other Android devices, and it seems pretty poorly actually ( Not that you can tell from the phone itself, it's silky smooth ), which is good news as the game isn't dropping too many frames on it. Anyone with a newer phone / tablet should get a really good 30fps experience with it.

And before this turns into an advert rather than a dev update I'll wish you a fond farewell until next time.

Squize.

PS. Outpost:Swarm should be gold, or near as damn it, we're hoping for final feedback this Friday, so hopefully some news about that soon.

Week III

I was in two minds about posting this, the past week or so have all been about Outpost:Swarm so DN8:Pulse hasn't progressed much, but I've had a stupidly productive day today so take my hand as we talk about new things.

As you can see baddie bullets are in now. They didn't take long at all as I'm lifting so much code from the original DN8 its almost obscene. To test how well the game copes I just get each baddie shooting a bullet every frame, and even with all those bullets with a blendMode we're not dropping a frame. Nice.

I added the floating points to the game the other day, updated the skybox to make it more colourful, altered the baddie explosion particles ( I spent hours on Friday doing that, and the end result was just dog shit, I mean really bad, so I ripped it all out and started again ). Last night that little planet in the background you can see there gained a ring ( A sphere with it's z scale set to 0.1, then rotated around ).

Today after the baddie bullets I've been working on the level progression code, and it's nearly there, and to celebrate I nailed down level 1's attack waves, so that level is officially done. It's amazing how one good days coding can give you a real lift.

And I think that's enough for Pulse this week, more soon...

Squize.