Wednesday, March 03, 2010
I just noticed that when getting back to the prototype of "Dial Z" to continue with it. The best thing I could do with it, was to file it away (yeah I know it's just a pretty way of moving it to the trash).

I'm pretty sure I've nailed the control scheme for the time being and I did a lot of planing on this one before I started coding (I usually do, just not to this scale).
Brainstorming into a mindmap was quite fun and it revield a lot of things that needed reduction in order to get a game out of it. Being able to use it as a kind of todo sheet also helps to keep the bigger picture in view.

Hellstrom_00.jpg

Speaking about views ...

First thing I'm going to code today (ok, start coding) will be the viewport. To get the "features" I want for it I'll need to do some rewriting on my tilebased scroller.
My first idea was to just use 2 of them with 2 additional layers for walls and sprites inbetween. In theory this would work out but also waste a good deal time, because some of the loops will have to run a few times. First for the floor scroller, then for the walls and last not least for the top scroller.

Combining that all into a speacial viewport class (and maybe reuse it later) will take some more planing and a good deal of copy and paste...

But first have a break and return to the dungeon generating code and see how I can fit the maps into the new scroller.

Well, we'll continue with this interesting post right after the next comercial. Or tomorrow.

nGFX

Wednesday, March 03, 2010 2:31:40 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  |  Trackback
 Tuesday, March 02, 2010
I've finally done enough non-game related stuff during the last couple of month that I really want to do a game now. Fiddling with easier concepts at first (read: the odd quick-money-game-in-a-day), I realized that's not what I want. There is a game that I'm thinking about for ages, which I have planned through in various stages - just to abandon it for something that promised to be done much quicker.

There is a certain pride to swallow when going down the quick money way and right now I'm not in the mood to do so - I want the real deal, a big game.

Walking down memory lane to the point when I went away from VB to make games - flash 5 was just released - there were a few holy grails for the game making flash world, the full blown RPG (only 2 kingdoms from our mate Lux I can remember to have played more than just a minute) and of course the odd Zelda(tm) clone (yet again only a handfull have seen the light and I can't remember to have played a single finished one).
Mine has been an "exploration game with random levels" (but you might have guessed that from the rnd level generation articles a damn while ago).

I'm quite confident that this time ... well we'll see.

Anyway, back to the title of this post - control.

I think one of the ways a player connects with the game is the control scheme - if the player doesn't like the controls, the game has to offer a lot more to make him want to play it. So let's have a look of what options there are.

But before I go into detail, a quick description of the game this controls are for:
  • the player moves his character around a map
  • the player needs to be able to shoot and/or attack enemies
  • the player may need switch between "weapons" (or alternate attacks)
  • the player needs to access some sort of inventory and interact with the game's menu

mouse control only

There are not many ways to imagine how this might work out, but here we go. Point the mouse to a spot where the character should go and click. OK, so far it works, IF we had a second mouse button (like the right click) we could assign firing a weapon to it. We cannot use right-click in flash (at least not for this purpose) so either we use a key for alternating click actions (space, ctrl or shift come to mind) - but that kind of defeats the idea of using a mouse only control. Though we could use icons to switch between modes (walking / firing), I doubt it'll really add to the experience, as it trades ease of control with rather complicated handling.


keyboard only

At a first glance this might be a good way to go, but I'm talking about real keyboard only control, read: not even using the mouse for menus ... and that's as much fun as it gets. My Virus game did that - and it worked surprisingly well, but consider that for navigating through a shop or your inventory. Yeah, fun - right.


moving with keyboard, aiming with mouse

Honestly I hate that. I know I'm in the minority here, but for me this only works well for "real" ego shooters (the good old Quake for instance and then I do prefer playing on the 360 using a controller), for a top-down view game it really turns me off. The first reason is that usually A,W,S,D is used, which I can use to move back, forth and strafe in something like Quake, but moving a character with that - I'm way to slow to dodge bullets or move precisely. Using the cursor keys is not my cup of tea either because they are too far away from any other key and it just feels not confortable to play this way (using the left hand to use the cursor keys). Still I have to consider this as alternative (and need to think about making the enemies harder then).


moving and aiming with keyboard, using mouse for interaction

Yes, that's something I can work with. My idea right now is that you use the cursor keys to move your character and just shoot in the same direction you're walking - pretty old school. In an early (and infinished flash 5 game I found on my hdd) this worked well when adding some sort of "lock" to the firing direction, so you could fire single shots into the moving direction or hold fire for a half second to "lock" the direction and then move freely while still firing into the locked direction (as long as you hold the fire button).

If you have your own arguments about how to control such a game, well just leave a comment.

nGFX

ps: Today is also the first development day, I hope to get the basic viewport coded using two tile based scrollers and a few distorted bitmaps - if things go well and I don't forget it there will be something like the x development diaries.

Tuesday, March 02, 2010 11:28:09 AM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [6]  |  Trackback
 Monday, March 01, 2010
We're at the start of week 3 of the new game, Destroy More Cars, which unsurprisingly is the sequel to our Destroy All Cars game.

It's the first outing for our blitter engine, so I thought I'd touch on that quickly.

dmc_grab1.jpg



If you've read the previous post you'll see there that I recommend a blitter engine for CS5 / iPhone development so I've been working on ours so it's there ready for the next project.

At the core of the blitter is the Canvas class. This holds the bitmap we're plotting to, does the lock / unlock thing, clears the canvas when needed ( By copying the background bitmap on there rather than fillRect ) and calls the children display objects.

Next up is the PlayField class. These are in effect layers. When I code I usually create sprites as holders and add these to the stage in order to simulate IDE layers, the PlayField class is just the same really.

At the bottom of this hierarchy are the building blocks, the Bobs. These are just simple sprites that are plotted to the canvas using copyPixel ( I've started work on a ComplexBob class which uses draw(), slower but it supports all the things that copyPixel can't, such as scale, alpha, rotation etc. Pain in the arse to code though, so slightly on the backburner and I'm just using bitmap's as simple sprites in the mean time ).

To make this truly useful I've tried to copy the existing DisplayObject as closely as possible, so for example if we've got an animated bob we can use bob.gotoAndPlay(bob.currentframe+1), to add a bob to a playField it's as simple as playField.addChild(bob) etc.
Depth sorting is in there too which makes life so much simpler ( The PlayField class is basically a list manager, making sure the bobs are always in the order we want. That's all depth sorting is really, just specifying what order to plot things in ).

One thing I stumbled upon the other day was the very sexy stage.invalidate(); To put it simply it's a way of flagging up the stage has been made dirty ( Altered ). If you have a stage.addEventListener(Event.RENDER,update);
listener, then when a stage.invalidate() is called at the end of the frame just before plotting everything our update method is called ( Via the RENDER event ). This means we don't have to call the update method as we usually would during our enterFrame main loop, in effect it handles itself, like the real display list does.

With using that, Vector lists which we loop through, lock / unlock etc. it all runs pretty quickly. Benchmarks I find are always a bit throwaway unless they're part of a really detailed set of comparisons, it's so easy to put a bit of spin on them to prove your code is the fastest.
Obviously I can't be bothered to do proper benchmarks, so prepare for some spin. DMC is running 6 layers of parallax on a 640x480 screen. It's got a handful of box2D objects ( The images are bitmaps rather than plotted via the blitter ) . In the screen grab above I think it's running 70 rain particles, but when I was testing I cranked that up to 500 just to push things. We've also got up to 80 glass particles ( Those little blue pixels at the top right of the grab ), soft particles for the smoke ( It's the first time I've used for particles for that as opposed to just pre-rendered images ) and there are 20 bits of debris spinning around in 3D, along with car door which rotates around in 3D too. With all that running it didn't drop a frame, stayed at a rock solid 35fps.

I think damage maps may speed things up in certain situations, but I'm more than happy with how it's performing right now, so that can be done if it's needed.

And that dear reader is how our blitter works.

Squize.

Monday, March 01, 2010 10:46:19 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Friday, February 26, 2010
I hate using such a search engine friendly title to a blog post, we normally bask in the willfully obscure, but as this may actually contain something of interest as opposed to the usual random words I figured it was worth at least trying to vaguely flag it up.

Let's start with a big caveat. I developed Zap using the beta version(s) of Flash CS5, and due to it's very nature it's not the final finished product. That means a couple of things, firstly that the launch version is going to be better than the one I used, the Flash team are really breaking their necks with the iPhone exporter and just doing great work. Secondly as it was beta software things are pretty fluid. I really honestly doubt that there are going to be any major changes so soon to release, but some of these tips may not be valid on release.
One last thing, being on the beta program means being under a NDA. In terms of this post it means I won't be going into technical things, performance or new API's etc. Think of this more as a primer which can hopefully give you a little head start than a sneak peek at what's under the hood.

Ok, the main thing is eeking out as much performance as you can.

* Vectors / Drawing API / Gradients. No, no and no. We're bitmaps all the way baby.
* BlendModes. Think more about burning the effect you want onto the bitmap itself.
* MovieClips. Save them for intros and title screens, avoid them in-game, as you just can't cache them efficiently so you're hitting the slower vector plotter.
* Text. It's slow enough when running in a swf. Time to code yourself a text plotter using bitmaps ( Like Movieclips, for in-game anyway. Top and Tails performance is never really a big issue )
* CacheAsBitmap. He's going to be your new best friend, love him and cherish him, as he'll give you much better performance ( There is a new cache command too, but NDA and all that ).
Some things to keep in mind, setting sprite.visible=false wipes the cache, so when you use sprite.visible=true again you're forcing a re-cache. Altering the alpha property also forces a re-cache ( As does scale etc. All the things I'm sure you're aware of any way ). One thing I didn't know before starting on Zap was that if you holder.removeChild(sprite) the cache is lost too, and that the cache only kicks in when the displayObject is first added to the stage.
In terms of how that hit my workflow, I had to change up and create all my sprites / bitmaps in each classes constructor and add them to the stage hidden off to the side.
When you first launch an app on the iPhone the "boot" picture appears straight away. Make sure that the very first thing you do is have a copy of that same image sitting topmost on your stage. Then you can call all your constructors and create all your display assets hidden under that cover, and when everything is in place you just transition that screen out. It hides any nasty stutters whilst the game makes everything it needs ( Using Zap as an example, the boot pic is our logo with "loading" text displayed on it, with the same image minus the loading text in the game itself, so the change from bootpic to game is pretty seamless ).
* Every pixel counts. Only plot what you need to, abuse the swf background colour as much as you can to save plotting.
* Pooling. Hopefully this is something you're used to doing anyway, but it's really vital when exporting to iPhone. During the constructor stage of my game I created all the pools too. Just using a simple Vector list, or linked lists. Pooling is such a simple thing to do and avoids any more object creation / deletion and stops the garbage collector being a big fat processor hog.
* Music. That loop that doesn't sound too bad on your PC at 32kps sounds really nasty on your iPod, funny what with it being a music player first and foremost. It's not a web game, push that bitrate up.
* scrollRect. I usually use that for animating bobs ( Blitter objects, ie sprites you plot with copyPixels or by adding the Bitmap directly to your stage ), using it to view a window on a sprite sheet to make it look like a sprite is animating, all nice simple stuff. I only had the briefest of tests with it on the iPhone, and I think it could be a texture memory hog, so the best way may be to just copyPixel each frame as you need it ( I've really not tested this to death so this could be complete arse, I was using a really big sprite sheet, so for now take this point with a pinch of salt ).
* Think blitter. Our good friend Rich showed me a blitter engine running on the iPod and it was really impressive. Blitting really is the way to go, just one canvas and plot all your pixels to it. I've just finished our own blitter engine for the up coming "Destroy More Cars" game which will be handy for future iPhone games. I'll post more details about that another time ( I'm tempted to open source it, but I really can't be doing with "This feature doesn't work" feedback. It doesn't ? Write your fucking own then ).
* Petty things. Mark your classes as final where you can, don't divide by two when you can multiply by 0.5, stop events from propagating. All tiny tiny things, but every little helps.
* Remember startDrag ? Sure you do, we all used it back in Flash 5. You're designing for the sexy iPhone now, it's not a mouse interface, let the player drag things around in a sexy way, they'll love you that little bit more for it. Apple have lots and lots of style guide docs, give them a read, it still applies to us even if we're Flash kids.

In terms of workflow, if you use Flex or FlashDevelop then you're not wanting to go back to the IDE in a hurry, it's too much of a shock to the system. I stuck with Flex ( By that I mean coding as3 in it, not mxml, there's still so much confusion about it even now ) and with including the AIR swc got auto-complete goodness on all the new commands. Lovely. Because Zap doesn't use anything really iPhone specific that needs to be on the device to test, I just added a simple test. If it's running via Flex check the keyboard and use that, if it's on the device don't run the keyboard code and revert to just mouse events.
I can't emphasis how much time this saved. You surely know the difference in compile time from Flex / FD compared to the IDE anyway, who wants to go running back to that ? It's not always going to be possible, but where you can make a version that can be tested off the device.
( In saying that, still test often on your device just to ensure that you're getting the performance you expect ).

How I set it up was having an empty fla with the iPhone publish settings in it, which just pulled in my classes. With CS4/5 supporting <embed> you don't have to change a line of your code, just use a different fla for laying out your assets for import. Using an empty fla just feels cleaner to me ( In actual fact I used two, one for testing and one for distribution, as you have to use different certs / profiles for each, more on that below ).

Moving on to Apple related things, brace yourself, this isn't the same as uploading a game to newgrounds. We've all read that getting a game published on the App Store is so easy and pain free, but that's mainly coming from people who are more used to the hell of developing for consoles, not Flash.
You're going to have to pay your $99 or whatever it is to register as a developer with Apple. My advice here is just register as a person rather than a company, it's a lot less hoops to jump through, plus when it comes to the App Store you can use a company name anyway which is searchable.

Next up is getting a cert and provisioning profile so you can test the game on your device. On the Mac that's fairly straight forward, on Windows it's a couple more things to do, our mate Iain touched on it in his blog post about his iPhone game. Come launch time I'm sure the web will be sinking under the weight of tutorials on how to do it.
One thing with the provisioning profile is that you can add devices to it. We couldn't really get access to any non-3GS / 3rd gen devices which restricted our testing, but you really want to be bugging everyone you know with an Apple machine for their device IDs so you can send out builds of your game for testing.

Come the glorious day that your app is ready to submit remember you'll need a distribution profile and cert. Also remember to re-read all the Apple guidelines, you don't want your game knocked back because of a silly mistake. You'll need to supple a link to a support site for the app, so prepare to remember your html skills that you've forgotten ( We just used the zap preview page, added a link to the contact form and job done. We've got a pimping and support page all in one ).
One last submission tip, when setting the release date, set it off in the ( Near ) future. If you leave it as todays date then when the game is passed at least 2/3 days after todays date it will be hidden in the latest releases ( Say you submit your app today, the 26th, and leave that as the release date. The game is accepted on the 28th. Your game will be classed as being launched on the 26th even though no one can actually buy it 'til the 28th, and even then it's got to filter around all the worldwide App Stores. This means all the games released after the 26th will be shown above yours in any latest games list ).
Once the app is approved, dive into itune connect and alter the launch date to tomorrow.

I think that's it. Hopefully I've not said anything I shouldn't have and got myself into trouble. If I have then I'll just lie and say my Mum is ill and start crying, no one will give me a bollocking then. When you do finally get your hands on the brand new Flash CS5 have a good google around for Apple developer forums. Every possible problem you'll ever have with submitting game has already been covered off by other people, the iPhone development community is huge and excellent, imagine our community without all the "I need teh codez lol!" and that's pretty much it.

Squize.

Friday, February 26, 2010 1:32:12 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [11]  |  Trackback
 Tuesday, January 26, 2010
Development of our first bit of iPhone goodness is coming along nicely. The game is an actual working game now, and plays quite well. As you can see the look & feel has taken a major change in direction from the first screenshot the other week.

zap_ingame.png

The glow look & feel just looked toilet. Without being able to use Blendmode.ADD like you would on a normal Flash game and other feedback effects it just wasn't working. It looked like someone had just discovered the glow filter and was dropping it onto everything.
So after a bit of feedback I decided to go for the faux GameBoy look. It's what I was planning originally anyway for the game I shelved. As it progressed I realised the game was missing some character, so out came the JBJ Sisters. They were characters in only my 4th ever Flash game and the only real character based IP I think we've ever done ( You should know by now we're more big slabs of metal and big lazers than identifiable characters ).
Straight away the game got an injection of life, which I'm really pleased with. And the best thing ? I did a remix of the original JBJ Sisters, the "Milk it mix", and that was my first flirtation with making something look like a GB game. So I've got all these GB coloured assets that hardly anyone has ever seen which weren't doing anything and needing a home.

One other major plus is that all the images are 8 bit, there's no alpha blending going on there, which really improves performance. The change has been a major win all round.

The game itself is based on the skeet shooting event in HyperSports. Not the first time I've coded this game, we did a version at preloaded back in the day called Shootin' StarZ, so I knew it worked as a game, and fits the device nicely ( Those two gridded areas you can see are your thumb buttons, it just feels nice in terms of input, straight forward and direct ).

When it comes to changing my game structure for the iPhone, it's really not been too bad at all. I'm still developing it in Flex3 ( And thanks to Rich I've got auto-complete on the new API stuff too, which is really rather lovely ) and doing all the testing with a normal swf with keyboard input, and just publishing it for the device to test performance and new graphics ( They do look different on the ipod than onscreen ).
This means my workflow hasn't been hit by long publishing times, which would have stopped me working on this long ago.

The major change was to do with when to trigger my constructors. I normally don't create class instances until I need them ( Ususally in the startGame() method ) but this was causing a noticable pause when going from the title screen to the game, so I call them during the "preloader".
Basically when an app first runs a bitmap is displayed straight away, then once the app is loaded it cuts to the app itself. All I've done is made the first screen in the game match the initial bitmap ( A big GYW logo, naturally ) so when it cuts from the bitmap to the game there's no change. I can then call all the constructors there under cover, and they set up all their object pools etc. before fading that logo down to the title screen. Nice and simple and effective.

Next up is fleshing out the presentation and giving the game some love and we should be good to go.

Squize.

Tuesday, January 26, 2010 3:15:05 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Wednesday, January 20, 2010
I see a lot of blogs where people tell us all how to make good games. It seems lots of people have something to say on this subject, even if they've only got one or two games under their belt, and then of dubious quality.
Some posts are truly inspiring, they show common gameplay / design issues in a new light that just clicks in your head, that "Shit yeah" moment when you connect with someone else's words in such a way that your own thoughts are solidified.
Other posts are like a tick list of game design. Responsive controls. Fair collisions. Give the player lots of power-ups. Shops, shops are always good. Sigh.

Rather than me force my view of game design down peoples throats ( I still only consider myself a so-so game designer, I've got better, but I'm far from good. If I was good I'd be confident to lay out my golden rules, but without me being able to say "You know that game I did, that you loved and played for hours ?" and all of you agree, I don't think I'm too well placed to hand out the testament according to GYW ), I thought I'd take the other tact of explaining why some games have faults.

Sometimes shit bits in games aren't due to the developer being shit. There, I've said it.

How many of us have posted a game to a forum and died a little inside when having to read "It's good, but if you did <whatever> it would be better" ? Or the classic "It'll be good when it's finished" after the person playing it has just played it on the client / sponsors website. What part of that obviously been finished haven't you noticed ? Don't get me wrong, no one's above feedback, and you can't post a game and expect everyone just to gather around you in a circle in awe. For the most part the feedback is spot on. When it's not though, it jars like nails down a chalk board.

We don't live in a utopia where every game is released when it's finished just how you want it. There are developers who release their magnum opus, and when asked how long it took you hear "Over 6 months", "Around 9 months" and so on. That's great, that's games as art in their purest form. That's not game development as a viable living though. That's game development as a hobby, a break from the day job. If you spent 6 months on a game, well fuck, it should be exactly how you wanted it, there's very little reason for it not to be aside from technical ability or the ability of collaborators.

In the temple of making a living wage with games, things are different. You have a budget to work to. If it's a client game then you have a deadline as well as a budget, not to mention the client themselves.

  • If you're doing a project for a client you usually have a set amount for the project. That includes designing how the game will play, prototyping if need be, some times creating custom engines or getting your head around 3rd party libraries. It means getting an artist on board if you don't work with one full time, giving them direction, sorting out a sound guy too. It means showing builds to the client and waiting for sign off, and dealing with amends. Some where during this time you have to actually ensure the game is fun, it's not a God given right that it will be just 'cause you've done a game design doc. Also you've got bug fixes and testing.
The vast majority of your time is spent on getting the features in, getting the game to be what it should be and just working, that things like multiple iterations and tweaking the difficulty curve are just a luxury. You can go over the budget and swallow a loss to devote more time to the more neglected areas, but by over delivering you're doing more work for less money. Good developers do that, but there does become a point of ever decreasing returns, where the extra hours being thrown at a game aren't giving you enough back in terms of cost vs quality.

This isn't just a client based issue, even if you're doing a game for sponsorship you've got to have one eye on budget. You know roughly what your game will bring ( Whilst secretly hoping for more ), and you have to avoid slipping into making that magnum opus which will only ever at best earn a fraction of the development cost back. If it's a business then it's got to be about the money as well as the art.

This is sometimes why a game isn't as feature complete as you would like, this is why you're aware that "If you did <whatever> it would be better", but unless that avatar on the forum with all the wise words is going to pay you for that extra time, it's not going to happen. It's not a lack of love for the project, or ability, or vision, it's called paying the rent.

  • Deadlines. There's never enough time to do what you want, so corners have to be cut as you need to hit that deadline ( Whether it's for an ad campaign or that Halloween themed game that has to be sold to a sponsor in a very tight time window ). That's not always skimping on levels, only doing 20 where 30 would be better, sometimes it's nasty kludge fixes to your code where you hope that the bug you get every now and again is so rare now that it's just magically gone away as you've put some heavy handed code around it to force it to work rather than re-coding the whole routine.
Again things like tweaking the difficulty and testing are hit. Yes, if you press the mute button over and over the title screen hangs, thanks for finding that and pointing it out, I just wish I had the time to test that myself rather than just doing everything else.

  • Clients come in all shapes and sizes. Some of them are great, some of them are not quite as great but still nice ( Yeah I can be faux professional ). No matter what though, they'll want some input. This varies from changing the colour of some text to sweeping changes that push you right up to the deadline, to gameplay changes which just break the game. The adver-game you see is never the developers pure image of what the game should be.

So if you're not a game developer, next time you're looking at a game, and you're thinking "How the hell could they release it with that bug / missing feature ?" hopefully some of the above will explain why. Yes, some games are just plain crap, but sometimes every once in a while a good game under achieves. It doesn't mean the developer doesn't give a shit, or isn't insightful enough to realise that it would be better if it did x,y and z, it means they've got rent to pay and that some times that gets in the way of making a truly great game.

Squize.

Wednesday, January 20, 2010 1:04:47 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [4]  |  Trackback
 Tuesday, January 05, 2010
With Ionic in bidding hell ( Really, it couldn't be going any worse at the moment. I think a game about rape would be an easier sell ) it's time to start on the next game.

I've got a vague idea of what I want, and what platform it's going to run on, and the background colour is set ( #B5C7AD ) and that's about it. Acorns and Oaks and all that.

Oh, and it's going to be called "Andrew".

More as and when.

Squize.

Tuesday, January 05, 2010 7:39:42 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  |  Trackback
 Monday, December 14, 2009
Not really much to say, aside from Ionic is officially gold and up on FGL panting for someone to pay money for it. It's a whore of a game.

ionic_FGL.jpg

Squize.

Monday, December 14, 2009 7:01:27 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [6]  |  Trackback
 Sunday, December 13, 2009
The 13th already ? And not a single post.

Like everyone else in the world right now we're just buried in work / seasonal joy.

As an ultra quick recap regards Ionic, I'm just finishing off the Juggernaut baddie right now. I think it's the only one which wasn't in the beta, so hopefully it'll come as a surprise. It's needing some special case code just for it, due to the sheer size of the sod. Also it's got multiple weapons, like all good bosses should.

Hopefully he should be done in the next couple of hours, then it's just tweaking and adding the remaining attack waves, dropping the final assets in from Lux ( Who has done such an excellent job, especially seeing how he came to the project so late and has had to cope with the programmers thing of "NO! It's got to be that size for a reason", which all artists hate ), the final credits at the end for when you complete the game, which are still in draft form as I keep remembering people I forgot, and we should be good to go.

We're still looking to have it up on FGL by close of play tomorrow, and like every big project it's hard to get your head around the fact that the finishing line is in sight at last. I'm sure it'll be tweaked and prodded once it's up there.

We are really looking forward to how it does once it's up for bidding. It's quite a risky experiment doing a AAA game like this, we're really not sure if it will pay for itself, never mind fund the next game. We have a psychological figure in mind that we want it to hit, so long as we get that then everything else is gravy.
In saying that, even if it dies on it's arse in terms of money, I couldn't really care less ( Well, being able to pay the bills would be nice ) as it's the best game I've ever done and I've been so lucky to have the support of so many friends during it's development. Ah, that's beautiful.

I really can't wait until the blog post with the games official link. Hopefully we'll be able to get it out before the end of the year.

Squize.

Sunday, December 13, 2009 5:37:17 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [4]  |  Trackback
 Friday, November 27, 2009
About two weeks later than I originally planned here's the beta of Ionic...

...but first the list of caveats that always go hand in hand with a beta.

* The title screen image is brand spanking new, ie just in there today. I'm not a 100% happy with the flow yet, it needs some tweaking.
* The animated planet is brand spanking new too, so I've not had chance to test it performance wise. It looks like it could be a cpu melter, but hopefully not, 'cause it does look sexy as hell.
* All of the baddie images are placeholders, borrowed from cronusX. It will look more varied.
* The music is a placeholder, nicked from one of the Alien Breed games I think.
* The HUD is going to change, I've got the assets, just not the time to drop them in just yet ( So the door edges which obscure it slightly now won't in the final version ).
* Lot's of little things that need some final love.

I imagine there are dozens more things that I've forgotten to mention, you know how it is.

With this beta I'm basically after views on the gameplay / balance / instructions. Is it fun ? Does it work like you'd expect it to ? Did you manage to complete it ( Or did you give up first ) ? Did you even feel the need to complete it or was is just leaving you bone dry instead of gushingly damp ?

Basically I'm after everything and anything that springs to mind. The more honest the better, if you think it's shit feel more than free to say so, although try and justify it a little please ( This isn't Kongregate, although you will get a point for posting ).

Ok, enough of me being needy. Thanks in advance for taking the time to give it a bash.

<Link removed as the game is gold and up for bidding. Thanks to everyone who played it>

Squize.

PS. I've noticed on the mac running Firefox the scanlines on the radar magically get in the way, making the cursor flicker like a mare between the handcursor and the normal one. If you get that on a non-mac machine let me know please. Joy.

Friday, November 27, 2009 5:42:23 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [16]  |  Trackback
 Wednesday, November 25, 2009
ionic_mtb5.jpg

Shockwave

ionic_mtb6.jpg

Spray Shot

ionic_mtb7.jpg

Missiles

ionic_mtb8.jpg

EMP

ionic_mtb9.jpg

Tesla

That's it. Maybe a beta this Friday ?


Squize.
Wednesday, November 25, 2009 6:54:16 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  |  Trackback
 Tuesday, November 24, 2009
ionic_mtb1.jpg

Machine Gun

ionic_mtb2.jpg

Lazer Cannon

ionic_mtb3.jpg

Shield

ionic_mtb4.jpg

Flame Thrower

Squize.
Tuesday, November 24, 2009 2:08:47 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Sunday, November 15, 2009
Still working on Ionic. It's taking a lot longer than I originally planned to be honest, it's grown into quite a monster.

Because of this our blog posts have dropped off the past couple of months ( Not even a Halloween post this year, which I think is a first for us), where we've not had much to either release or show. There is a cronusX post mortem to be done, but since my host got hacked ( The host was a cheap one which was just to be a dumping ground for our games, it's not the main host on which both this blog and the site ( Along with the client area ) sit ) none of the development pages are online, so until we sort something permanent out there I've got to hold fire.

Speaking of cronusX, the cock who obviously doesn't like me on NG is still voting it down every day. It's about 3.55 from 3.81. Let's wish him luck with blamming it. Prick.

Anyway back to Ionic. After this post is submitted I'm back on adding the last turret type, which will give us 9 in total. Hopefully I can use a lot of existing code, so most of the time will be spent adding the help text for it ( There's a lot of text in this game. It's set up so you don't have to read any of it if you don't want to, but you'll get a better insight if you do ) and then testing it against various attack waves for balance.

We're getting close to the final push now. In terms of gameplay it's only really come together the past couple of weeks, which has been the main reason I've not been posting about it more here or releasing lots of builds like we did with cronusX. It's actually enjoyable to play now, to the point that it's disappointing when you complete the limited number of attack waves that are in there at present.
A lot of the presentation has been added as I've gone, which has taken longer ( I've still not drawn one baddie ship yet, which I'm really dreading ) but it means it won't be a case of the game being finished and then having to do another love pass on it.

The milestone of it being a "proper" game was hit last week sometime, so there is a game complete sequence and a game over one. It's all coming together.

As way of a filler, I've attached the dreadnought as it is in the game, here's the HMS Ionic

More news and grabs as and when.

Squize.

Sunday, November 15, 2009 12:44:12 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  |  Trackback
 Wednesday, November 04, 2009
I've got a bug in Ionic. It's with the little remote drones that collect the dropped guineas ( I thought guineas made a nice change to "Creds", plus I'd already done the spinning G graphic for the never to be released Orbs game I started on. The power-source you have to protect in the middle of your dreadnought in Ionic also funnily enough looks just like the orb from Orbs. No point wasting those pixels ).

Anyway, the drones are called "Chrysus". It's from Greek mythology, and he ( It ? ) was the spirit of gold. Naming things is always an important aspect of development for me, it helps settle things in my mind, it sets a tone, and I like that name ( Even though I had to check the spelling lots of times when first getting used to it. And edit the blog just now where I've spelt it wrong. Classy ).
It says what it is nice and succinctly.

Why am I even talking about this ? Yes partly 'cause our posts have dropped off recently, we're just having a boring phase where everything we do can just as easily be condensed down to a 140 words and spat out over twitter ( That's so cheap linking to our twitter account I know ) but partly because all the in-game help is done now.

All finished.

The snag is, no where in the docs do I explain the Chrysus.

The game is quite word heavy, the detail is there if you want it. I've not explained the drones / guineas as I like to credit the end player with the intelligence to figure things out ( Unless of course you're that first poster type on Kongregate. Anyone who can post a comment within minutes of a game being uploaded is someone whose not actually taken the time to play the game they're so keen to say sucks. First posters, you may think you're the Billy Bollocks for getting there first, but I think it's fair to say the majority of developers think you're a cock. And ignore your comments anyway. Well done for "winning" though, good work on that ), and get that "Ah, I get it" moment that is the reward of sticking with something.

So no mention of the word Chrysus anywhere in the game. Bit of an over sight ? Possibly. But I'd have to name it anyway, it needs a class name, and now it's our little secret. Think of reading the blog as buying the limited edition of the game, you're getting the inside scoop that other people miss.

And yes, right now I regret having a little green drone flying out of hatch to collect dropped coins instead of just adding them straight to your bank account like in other tower defense games. A drone with no name and a big fat bug.

Squize.

Wednesday, November 04, 2009 12:54:10 AM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Friday, October 23, 2009
Managed to knock up a logo I'm happy with last night, then added a bit of RGB Bumb Mapping, like so

ionic_logoGrab.jpg

Which looks really pretty when moving, and adds some much needed colour to a pretty drab game. In terms of cpu use it's pretty costly, but with only buttons on the title screen I should be able to get way with it.

The actual theory behind how to do the bump mapping was taken from the always excellent unitzeroone, then just ported to as3 and given a couple of tweaks ( The ADD blendmode is your mate here ).

Getting ever closer to it being a proper game.

Squize.

Friday, October 23, 2009 9:45:48 AM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Thursday, October 22, 2009
In between knocking out a Pac Man clone in a couple of days ( Not sure when that's been released, I'll be sure to pimp it when it's out there ), finishing off DAC and still working on the huge never ending Nat-Geo project, I've managed to squeeze some work in on Ionic.

ionic_machineGunGrab.jpg

If you've been following the few and far between updates you'll see that there are proper gun turrets in there now, those being of the machine gun variety. I've also nailed down the HUD look & feel, which took a lot longer than I planned.
In essence I'm trying to convey that you're looking at the battle from your monitor ( Possibly on the dreadnought itself, or remotely. I've not decided yet as I've not figured out how to blow up such a huge sprite ) so all the HUD overlays can be CGI looking. I'm trying to make it not look too much like cronusX but still feel like it's in the same universe. It needs that "Not done in Flash" feel.

ionic_shieldGrab.jpg

Lot's of things in this grab. We've got the lazer cannon turrets in there, which pack quite a punch but take ages to reload until you've upgraded them to their max. Also newly added today is the shield. That protects any turret in it's sphere of influence, reducing the baddies shot power to a quarter of what it should be.
Also on here we've got the "Slot menu", a quick way to amend your turret.

Slyly peeking around the corner is your 2nd in command, who pops up to relay information to you, such as when a new upgrade or weapon is available. As the game has a resource management aspect to it, you don't get all the goodies at once, you only start with 3 weapons and no upgrades. The more resources you put into R&D the quicker the new toys become available, but that's at the expense of the other areas of the ship you have to control.
And yes, the 2nd in command does look just like an ODST, placeholder atm.



The UX side of things have had a lot of amends the past couple of days thanks to the guys on the board, and it's feeling a lot more accessible now. There are a couple of annoying bugs, as always, but it's all going in the right direction.
I think next up will be the front-end, which means I've got to figure out what play modes there will be ( Feel free to offer up ideas ) and put the always heart breakingly nasty "More games" button placeholder. For the actual logo I'm thinking 3D text with a sexy bump mapping effect, which should be fun to actually get done.

Once the front end is in place I can actually make it a real game, with a start to play and a Game Over to look at, which is always a great milestone. From there it will be a case of drawing lots of sprites, finishing off the UI and throwing lots of data at it for the attack waves and all the in-game help / info.

Still tons to do, but it's all getting there.

Squize.

Thursday, October 22, 2009 12:15:54 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Friday, September 18, 2009
This is just going to be a short "So obvious maybe it's not worth saying" post, but lets face it, most of the posts here fall into that category.

The driving / crashing game I'm working on right now ( Look a couple of posts down to read very little about it. NDA's, they're like garlic to this vampire of a blog ) has a nice Star Wars wipe. I've used it a couple of times before, it's a simple yet effective transition, and it suits some games well.
In this case it fits as it reinforces the fast movement from left to right, which is what the game's all about. And you thought I just threw all these games together by blindly bashing on the keys until the errors stop. Ahem.

Anyway as this game uses box2D the results are very variable. A little tweak here and a little one there and it throws up totally different results, which in turn means a lot of testing. I must have seen the same screens thousands of times. I mean that literally.

The other day my beautiful Star Wars wipe got to the point where I couldn't take it any more. I imagine people who work in the porn industry get sick of it after a while, or a tour guide at the Sistine Chapel ( Now there's two extremes ). I'm going to shorten it to make it run quicker.

No.

Trust your instincts when it comes to the timing of things like that. If it looked great the first couple of times ( After tweaking of course. Nothing is right first time ) then it's right. Don't let your boredom get the better of you.
Many a time I've had to dig my heels in with clients where they've seen lots and lots of iterations of a game ( That's agile development for you ) where they've got sick of the same sequence I have, and suggested it be shortened.

Just say the same thing you would to a unkempt man with his arm in a sling asking you to just help him put something heavy in the back of his van, here, it's just up this dark alley. Just reach right in there and put it far at the back, whilst he stands behind you.

If you say yes to it, it will be the development equivalent of having to rub the lotion into your skin. And no, we don't want the hose again.

It's not just transitions, text too is something that it's easy to skip by too quickly. A simple rule of thumb, read the text yourself twice. Not coder read it, proper read it. Twice. Slowly. And that's how long it's going to have to sit there, no matter how many times you have to sit through it ( Before any one chimes in and says you just the reduce the time during testing and put it back to the original when the game's nearly done, I know, this is just design theory. Work with me here ).

Squize.

Friday, September 18, 2009 9:33:22 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [5]  |  Trackback
 Tuesday, September 08, 2009
Figured it would be an idea to actually talk about Flash work on here for a pleasant change. I've been quiet of late as to be honest nothing much has been happening. I've been wrestling with box2D for one project, finishing off another and working on the TD as a personal release.

Here's a little grab from the National Geographic project ( I can't say anything more about it, NDAs = not the best subject for a blog post )

natGeo_grab.png

We've been hit with a lot of amends on this project, but it's all shaping up nicely. I believe it's going to be a CD only release, possibly making it online at a later date. So that's a game I can't talk about that you'll possibly never play. This is why I haven't been blogging much.

Next up is a game I've been doing with my mate Elliot at www.MakingFunGames.com


dac_grab.png


Not the most gripping of screen grabs I know, but I think this could well be a bit secret too ( No NDA, but then no "Feel free to spill your guts about it" ). This is a box2D based game, and I'm not even going to start bitching about how hellish it is to get box2D to do something ( I did the pinball game way back, and so had forgotten everything I'd learned, which at the time was barely enough to get a ball moving with some flippers ).
I think it's going to be quite good when it's done, there is something pleasing about making cars crash for some primeval reason.

Both of these should be done and dusted by the end of the month.

ionicChyrsus_grab.jpg

This is the current build of Ionic, my TD game, which shows some nasty placeholder art for the turrets. The baddie shadow effects are in now, which I'm really happy with ( So happy I didn't actually manage to capture a grab of them in action ) plus some of the collision checks / shooting. One thing I added the other day is that little spiky drone just at the bottom of that top red box. That little drone, aside from needing to be scaled up and re-coloured, comes out of that open hatch on the far left there and collects any dropped coins when a baddie is killed ( See, he's heading for that obscured spinning gold G there ).

They say a picture is worth a 1000 words, aside from that one, which needs a 1000 words to explain it. Not my greatest prtScn moment.

I'm not even going to put a release date on Ionic, it's done when it's done. It's not me being all "This is my art, don't you understand ?", it's me being snowed under with other things, so this is my down time project.

Squize.

Tuesday, September 08, 2009 12:02:40 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [3]  |  Trackback
 Monday, August 10, 2009
I've been working on a TD game ( It's the law that you have to do at least one ) on and off for the past couple of weeks, and the main dreadnought graphics are pretty much done, so I thought I'd post a couple of grabs seeing how I've been relatively quiet here recently ( I moved away from London a week ago, and I'm suffering with things still in boxes and a mobile net connection, which is about as much use as tits on a nun, so that's why I've been a little awol )

ionic_grab1.jpg

ionic_grab2.jpg

I've not got much else to add at the moment. If you liked cronusX then you should like this, I want a mixture of TD and all out particle heavy shoot'em up. It's either going to work well, or fall flat on it's arse ( I'm thinking more the latter to be honest ).

Anyway more when I've got it. It's a bit of a stop start project as we've got a ton of work in right now, so that and real life is getting priority.

Squize.

Monday, August 10, 2009 5:32:14 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [8]  |  Trackback
 Thursday, August 06, 2009
So after the set of articles about random level generation I wanted to put that into use (alas not in the scale I planed it out - mind you) - so I came up with a nice little 3 week project - that was 5 weeks ago.

The basic idea is a simple top/down shooter blended with a good portion of Gauntlet added (hordes of enemies, maybe). And while it's fun to watch levels being created by code it involves a good deal of additional work, like changing the tilesets, adding dirt and stains.

The X entries seemed to be a good idea, so I'm going to publish a few wip builds soon, too (alas not as many as Squize).

In order to see something at all (except the test visuals from the article tests) I needed to convert the cell based dungeons into someting tile based, and write a simple scroller to display the created maps. I decided that each cell should consist of 6 by 6 tiles, so I could use a one tile wide border for the walls (if any) and still have 4 tiles walking space. Next point on the list was the question about how to store the data generated - as I didn't wanted to convert cells/tiles at runtime before they're being displayed. Storing them in an array seemed a good idea, but I wanted to try something new...

Not to mention that converting 50x50 cell dungeon would result in an 300x300 array.

After a few minutes I thought that using BitmapData would be a nice try to store the map, as it'll give me a quite quick direct access 3 dim array (x,y, R,G,B,A) which I could use multiple times. so I used the alpha chanel for the tileset, the red one for the actual tile, blue for pathfinding and green for effects/2nd layer.

Right, why storing a tileset?

In my idea each room has basically the same tiles (ie. walls, doors, corners and floor) and the conversion would be much easier if I would use the same tiles over and over. So I came up with storing tiles in tilesets, which offsets the tiles on the tilesheet.
The creation process is quite easy this way:

First I have to create a tileset and give it a name, say "Corridor".

myTileset = new Tileset("Corridor");

Then add tiles to that tileset, giving it a name and and x/y offset in the tilesheet (I wrote data class for that):

myTileset.addTile(new Tile("empty", 0, 0));
myTileset.addTile(new Tile("Floor00", 1, 0));
myTileset.addTile(new Tile("WallN", 0, 1));
myTileset.addTile(new Tile("CornerInN", 1, 1));


Internally I use the tile's index, but the cell/tile converter just uses the name:

if (!myCell.isUnused) {
                        
    iTile = myTileset.index(strFloor);
    iPath = 0
    iSpecial = 0;
    bmpdMap.fillRect(new Rectangle(xx, yy, iTilesPerCell, iTilesPerCell), this.rgba(iTile, iSpecial, iPath, iTileset));
    
    // walls
    for (i = 0; i < Dir.NUM_BASEDIR; i++) {
        
        if (!myCell.isOpen(i)) {
            cx = xx + aWall[i].x;
            cy = yy + aWall[i].y;
            
            iTile = myTileset.index("Wall" + Dir.shortName(i));
            iPath = 255;    // so you can't walk there (for the bool map pathfinding)
            iSpecial = 0;
            bmpdMap.fillRect(new Rectangle(cx, cy, aWall[i].width, aWall[i].height), this.rgba(iTile, iSpecial, iPath, iTileset));
            
            // door
            if (myCell.hasDoor(i)) {
                
                // door frames are painted "above" the floor, so I use the special layer for that
                iTile = myTileset.index(strFloor);
                iPath = 127;
                iSpecial = myTileset.index("Door" + Dir.shortName(i) + "0");
                bmpdMap.setPixel(cx + aDoor[i][0].x, cy + aDoor[i][0].y, this.rgba(iTile, iSpecial, iPath, iTileset));
                
                iSpecial = myTileset.index("Door" + Dir.shortName(i) + "1");
                bmpdMap.setPixel(cx + aDoor[i][1].x, cy + aDoor[i][1].y, this.rgba(iTile, iSpecial, iPath, iTileset));
                
            } // ToDo: add windows if possible ...
            
        }
        
    }
    
    // ... draw corner and outer coners [skipped]
}

Ah. Nice and easy :)

So by using a different tileset you can easily control the visuals of a room.

Next thing on the list: the scroller - more thinking here ...

I wrote the Scroller class as extension to Sprite so I could add my own sprites and use the Sprites scrollrect for clipping. Adding a Scoller to the stage became easy as 123:

this._Scroller = new Scroller(620, 460, 20, 20); // width, height, tilewidth and tileheight
this._Scroller.name = "scroller";
this._Scroller.x = 10;
this._Scroller.y = 10;

this.addChild(this._Scroller);

this._Scroller.setTileset(this._bmpdTileset, this._TilesetCollection);
this._Scroller.setMap(this._bmpdMap); // the freshly generated map
this._Scroller.setCenter(310, 230);   // alows offsettin the origin, so 0,0 can be at the center of the scroller

this._Scroller.xPos = 0;
this._Scroller.yPos = 0;
this._Scroller.draw();
// updates the visuals of the scroller

the way the scroller is set up (I still need to optimize redrawing, though) makes it possible to use it with tween utils like TweenLite:
TweenLite.to(this._Scroller, 1, [xPos: 100, yPos: 100, onUpdate: this._Scroller.draw});

So after a few days of coding it looks like this:
DialZ_pre_00_small.jpg
(scaled version)

The visibilty test is in place (you can only see the room you're currently in and vector boundaries are created (the green rect in the room, door triggers (blue rect)). The map in the left corner is shwoing the pathfinding bounds (helpfull for testing, too) and will be replaced by a minimap later (circular, hopefully).

Right now I'm writing the vector intersection methods (I'm using math instead of the tiledate for collisions) - so I thing the next entry will feature that.

nGFX

Thursday, August 06, 2009 12:28:03 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Tuesday, July 14, 2009
In the last two articles  we made a maze and then destroyed it by adding a lot of free space. In part 3 of this articles I'm going to add some rooms to the empty space and add some doors ...

Part 3 - part 1 - why seperate things and make rooms?

At a first glance it might not be necessary to seperate data into dungeon, room and cell, but thinking ahead a bit it should make sense ...
My idea is that you can have the dungeon which holds the complete map (with the basic room data rendered into it) and the rooms so you access them easier and most important do some magic with them later. One of the neat things is that you could use a different tiling for rooms making them more detailed or use the additional map data for skinning (when rendering the dungeon into a tile based map).

The main difference between a room and a dungeon is that the room consists of empty cells and has walls along it's boundaries. So the first additional method we'd add to the Room class will be the init method, which simply sets all cells so they form a rectangular room.

public function initCells ():void {
            
    var x:uint;
    var y:uint;
    var cellTmp:Cell;
            
    for (x = 0; x < this.iWidth; x++) {
        for (y = 0; y < this.iHeight; y++) {
                    
            cellTmp = this.cell2(x, y);
            cellTmp.setWalls(WallType.OPEN);
                  
            if (x == 0) cellTmp.setWall(Dir.WEST, WallType.WALL);
            if (x == (this.iWidth - 1)) cellTmp.setWall(Dir.EAST, WallType.WALL);
            if (y == 0) cellTmp.setWall(Dir.NORTH, WallType.WALL);
            if (y == (this.iHeight - 1)) cellTmp.setWall(Dir.SOUTH, WallType.WALL);
        }
    }
}

We could later add methods to create different rooms (ie. two overlapping rectangles, circular rooms), but for now that will do ...

I also added a getter setter for Offset to the room, so we can modify the x and y pos of the bounding rect that we stored in the map class (you'll see later what's that for).

So we now have a room, but how do we get that sucker into the map, or (as just putting it into the map isn't really an issue) where can we place it *best*.

There are a few things that I want to watch when placing the rooms ...
- a room should not overlap any existing room, we rather don't at it
- placing a room at a place where it doesn't touch anything, is something we don't want, too
- rooms overlapping corridors should be avoided
- rooms touching dead ends is something we want (what's nice than finding a room after a long winded corridor?)
- rooms touching any sort of wall is OK, too

Yet again we (as humans) could just look at the map and say "here, there and there" and done, but that stupic piece of plastic cannot... we need to apply some sort of scoring to the whole placement mess.

Here's a bit of pseudo code ...
  • start with a VERY high best score, lets say 999999999999 and set current score to 0 ...
  • Loop over every cell in the dungeon
    • at any given position check if the new room overlaps any rooms already in there
      if so, we add 5000 to our current score, otherwise we add nothing
    • now loop over every cell in the room and compare it with the current dungeon cell (offsetting the room to the current position)
      • if the current room cell touches an empty cell (in the dungeon), add 10
      • if we touch a wall, add 3
      • if we touch a dead end, add 1
    • if the final current score is lower than the best score, sreplace the best score and store the current position as the best possible location
  • if the score is higher than the "room overlaps room" score, assume that it only can be placed overlapping a room and drop it, otherwise add it to the dungeon
Here is the scoring code:

private const TOUCH_DEADEND:int = 1;
private const TOUCH_WALL:int = 3;
private const TOUCH_EMPTY:int = 10;
private const OVERLAP_ROOM:int = 5000;
private const OVERLAP_CORRIDOR:int = 100;
        
public function fitMazeRoom (myRoom:Room):Boolean {
    
    var iBestScore:int = 999999999;
    var iScore:int = 0;
    var pBestPos:Point = new Point(0, 0);
    var pOffset:Point = new Point(0, 0);
    
    var cellDungeon:Cell;
    var cellNext:Cell;
    
    var rectTmp:Rectangle = myRoom.rectBound.clone();
    
    var i:uint;
    
    var x:int;
    var y:int;
    
    var xx:int;
    var yy:int;
    
    var iRoomID:uint;
    
    var bAddRoom:Boolean = false;
    
    // loop over map (- roomsize)
    for (y = 0; y < (this.iHeight - myRoom.iHeight + 1); y++) {
        for (x = 0; x < (this.iWidth - myRoom.iWidth + 1); x++) {
            
            // do the scoring ...
            iScore = 0;
            
            // check room/room overlapping
            rectTmp.x = x;
            rectTmp.y = y;
            for (i = 0; i < this._aRoom.length; i++) {
                if ((this._aRoom[i] as Room).rectBound.intersects(rectTmp)) {
                    iScore += OVERLAP_ROOM;
                }
            }
            
            // check room/dungeon overlapping
            for (yy = 0; yy < myRoom.iHeight; yy++) {
                for (xx = 0; xx < myRoom.iWidth; xx++) {
                    pOffset.x = (x + xx);
                    pOffset.y = (y + yy);
                    
                    cellDungeon = this.cell(pOffset);
                    if (cellDungeon.iType == RoomType.CORRIDOR) iScore += OVERLAP_CORRIDOR;
                    
                    if (yy == 0) {
                        iScore += this.getCellScore(this.cell(this.getNextPos(pOffset, Dir.NORTH)), Dir.NORTH);
                    }
                    if (xx == (myRoom.iWidth - 1)) {
                        iScore += this.getCellScore(this.cell(this.getNextPos(pOffset, Dir.EAST)), Dir.EAST);
                    }
                    if (yy == (myRoom.iHeight - 1)) {
                        iScore += this.getCellScore(this.cell(this.getNextPos(pOffset, Dir.SOUTH)), Dir.SOUTH);
                    }
                    if (xx == 0) {
                        iScore += this.getCellScore(this.cell(this.getNextPos(pOffset, Dir.WEST)), Dir.WEST);
                    }
                }
            }
            
            if (iScore < iBestScore) {
                iBestScore = iScore;
                pBestPos = new Point(x, y);
            }
            
        }
    }
    
    // add to dungeon if it doesn't overlap any other rooms
    if (iBestScore < OVERLAP_ROOM) {
        myRoom.pOffset = new Point(pBestPos.x, pBestPos.y);            
        bAddRoom = true;
    }
    
    return bAddRoom;
    
}

private function getCellScore (cellNext:Cell, iDir:int):int {
    
    var iScore:int = 0;
    
    if (cellNext.iType == RoomType.CORRIDOR) {
        if (cellNext.isDeadEnd) {
            iScore += TOUCH_DEADEND;
        } else if (cellNext.hasWall(Dir.getOppositeDir(iDir))) {
            iScore += TOUCH_WALL;
        } else {
            iScore += TOUCH_EMPTY;
        }
    } else {
        if (cellNext.iType == RoomType.ROOM) {
            if (cellNext.hasWall(Dir.getOppositeDir(iDir))) {
                iScore += TOUCH_WALL;
            } else {
                iScore += TOUCH_EMPTY;
            }
        } else {
            iScore += TOUCH_EMPTY;    
        }
    }
    
    return iScore;
    
}

That's ugly and not very fast, but it works.

Some additional info about adding the room to the dungeon: whenever we place a room cell in the dungeon map it's a good idea to check if it overwrites a corridor and if it's a cell on the outer bounds of the room add a new wall to the touching cell (if it's not empty) ...

So far so good, we have rooms in the map, but they cannot yet be reached because we're missing doors ...

Part 3 - part 2 - adding doors and cleaning up

You might ask why I haven't added the doors as soon as I've added the room to the dungeon (and I might just reply that I just didn't mention it), but nope, I didn't add doors - that's the next step.

The reason is quite simple, though. I don't want doors cluttered all over the space and because of that I added another (optional) thing to the room data: hasDoorInDirection ... this way we make sure that there is only one door per wall / room when we add doors ...

Yet again we loop over all rooms and over their outer bounding cells, if we touch another cell, store the current position as possible door location. Then pick a random one per direction and check if it touches another room and if this room might already have a door ...
I guess that's easier to explain with some more code:

private function createDoors (myDungeon:Dungeon, bOneDoorPerRoom:Boolean = true):void {
    
    var rnd:MersenneTwister = MersenneTwister.getInstance();
    
    var i:uint;
    var j:uint;
    
    var x:uint;
    var y:uint;

    var cellTouch:Cell;
    var myRoom:Room;
    
    var aDoor:Array;
    var pDoor:Point;
    var pNext:Point;
    
    for (i = 0; i < myDungeon.aRoom.length; i++) {
        
        myRoom = (myDungeon.aRoom[i] as Room);
        
        aDoor = [[], [], [], []];

        // collect possible door locations ...
        for (y = 0; y < myRoom.iHeight; y++) {
            for (x = 0; x < myRoom.iWidth; x++) {
                
                pDoor = new Point(myRoom.pOffset.x + x, myRoom.pOffset.y + y);
                
                if (y == 0 && pDoor.y > 0) {
                    pNext = myDungeon.getNextPos(pDoor, Dir.NORTH);
                    cellTouch = myDungeon.cell(pNext);
                    if (!cellTouch.isUnused || cellTouch.iType == RoomType.CORRIDOR) {    // the check for a cooridor is needed because they might be just one cell long ...
                        aDoor[Dir.NORTH].push(pDoor);
                        if (cellTouch.isDeadEnd) aDoor[Dir.NORTH].push(pDoor); // double chances for dead ends ...
                    }
                }
                
                if (x == (myRoom.iWidth - 1) && pDoor.x < (myDungeon.iWidth - 1)) {
                    pNext = myDungeon.getNextPos(pDoor, Dir.EAST);
                    cellTouch = myDungeon.cell(pNext);
                    if (!cellTouch.isUnused || cellTouch.iType == RoomType.CORRIDOR) {
                        aDoor[Dir.EAST].push(pDoor);
                        if (cellTouch.isDeadEnd) aDoor[Dir.EAST].push(pDoor); // double chances for dead ends ...
                    }
                }
                
                if (y == (myRoom.iHeight - 1) && pDoor.y < (myDungeon.iHeight - 1)) {
                    pNext = myDungeon.getNextPos(pDoor, Dir.SOUTH);
                    cellTouch = myDungeon.cell(pNext);
                    if (!cellTouch.isUnused || cellTouch.iType == RoomType.CORRIDOR) {
                        aDoor[Dir.SOUTH].push(pDoor);
                        if (cellTouch.isDeadEnd) aDoor[Dir.SOUTH].push(pDoor); // double chances for dead ends ...
                    }
                }
                
                if (x == 0 && pDoor.x > 0) {
                    pNext = myDungeon.getNextPos(pDoor, Dir.WEST);
                    cellTouch = myDungeon.cell(pNext);
                    if (!cellTouch.isUnused || cellTouch.iType == RoomType.CORRIDOR) {
                        aDoor[Dir.WEST].push(pDoor);
                        if (cellTouch.isDeadEnd) aDoor[Dir.WEST].push(pDoor); // double chances for dead ends ...
                    }
                }
            }
        }
        
        // now just pick one door per side ...
        for (j = 0; j < Dir.NUM_BASEDIR; j++) {
            
            if (aDoor[j].length > 0) {
                
                pDoor = aDoor[j][rnd.Range(0, (aDoor[j].length - 1))];
                pNext = myDungeon.getNextPos(pDoor, j);
                
                if (!myRoom.hasDoor(j)) {
                    myRoom.setDoor(j, pDoor);
                    
                    if (bOneDoorPerRoom && myDungeon.cell(pNext).iType == RoomType.ROOM) {
                        myDungeon.getRoom(myDungeon.cell(pNext).iValue).setDoor(Dir.getOppositeDir(j), pNext);
                    }
                    
                    myDungeon.cell(pDoor).setWall(j, WallType.DOOR);
                    myDungeon.cell(pNext).setWall(Dir.getOppositeDir(j), WallType.DOOR);
                }
            }
        }
    }
}

Viola done ... but wait one more thing, cleaning up ...

The last step might not be needed, but imho it makes some nice dungeons: after we've added all the rooms and doors, we remove all remeaning dead ends. This way there will be no corridors just ending somewhere and the map looks nicer.

So we just run the removeDeadEnds method again, this time with 100% ... now:done.

As with the last parts, the link to a working demo of the whole mess is here or here.

nGFX

Tuesday, July 14, 2009 11:56:39 AM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [4]  |  Trackback
 Friday, July 03, 2009
This time it's one of ours! Seems like forever since we've had something of our own to talk about ( There will be another game on the 9th of July to mention too, but more of that nearer the time ).

AQI Zoneout is the fella this time.

zoneOut_grab.jpg



It's a really quite good puzzle game that I worked on for our friends at theBasement.tv ( Check their demo reel out, seeing that really made me want to work with those guys )

It was a slightly weird development process for me, as I broke off before the game was actually finished for various asset related reasons, so that in combination with it already been planned out really well beforehand stops it feeling like it's mine, it's more something I worked on rather than made, if that makes sense.

As a project though, it was a real joy and a real pleasure to get to work with ickydime on a game together, you couldn't ask for a better go-between at a company, and the work that was done to the game after it left my sticky fingers has really raised it up, there's a lot of love in there.

I was asked as part of this pimp to also mention Miles design who were the agency for the project, Fat Atom who did the sweet php magic so you can see your name on the high-score table and of course cleanairmatters.org who are the end client.

That's more than enough words, give it a go, it'll help eat into your Friday before home time, hurray!

[ Update, it's now on Kong and NG. So if you don't want to play it on it's nice custom page, go to either site and look at the ads whilst you play ]

Squize.

Friday, July 03, 2009 2:51:33 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Wednesday, July 01, 2009
I've found myself defending oop recently, and at the same time bemoaning the lack of good oop tutorials with regards game development.

Rather than promising to write a full blown tutorial, as to be honest there's no way I'll stick to it, after around 3 parts at most I'll be bored stupid, I thought I'd try and explain the structure behind an existing game which we've already posted the source to. So it may be an idea to open this link in it's own tab.

Ready ? Ok, let's go.

opCFlow.png


Look at that, made with a free package so you get the watermark, nothing's too cheap for you dear reader.

This at heart is how I've structured all my games since starting with as2. It only varies in that there are sometimes more classes in there, the actual hierarchy never changes.

Ok lots of code here is never that great to read, but there's no way around it, sorry,

package {
    import Classes.Init;
    
    import flash.display.DisplayObject;
    import flash.display.Sprite;
    import flash.display.Stage;
    import flash.display.StageQuality;
    import flash.display.StageScaleMode;
    import flash.events.Event;

    [SWF(width="600", height="400", frameRate="35", backgroundColor="#000000")]

    public class Main extends Sprite{

//---------------------------------------------------------------------------------------
// Properties
//---------------------------------------------------------------------------------------
        private static var instance:Main;
        private static var __parent:DisplayObject;
        private static var stage:Stage;
        private static var init:Init;
        
//---------------------------------------------------------------------------------------
// Static ( Singleton )
//---------------------------------------------------------------------------------------
        public function Main(){
            if(instance){
                throw new Error( "Singleton and can only be accessed through Singleton.getInstance()" );
            } else {
                instance=this;
            }        

            instance=this;
//When we are running from our preloader, comment this out
            waiting();
        }

//---------------------------------------------------------------------------------------
// Public
//---------------------------------------------------------------------------------------
        public override function toString():String {
            return "Main";
        }        

//---------------------------------------------------------------------------------------
        public function waiting():void{
            addEventListener(Event.ADDED_TO_STAGE,mainAddedToStage);
        }

//---------------------------------------------------------------------------------------
// Getters
//---------------------------------------------------------------------------------------
        public static function getInstance():Main {
            return instance;
        }

//----------------------------------------------------------------------
        public function getMainMovie():DisplayObject{
            return __parent;    
        }

//----------------------------------------------------------------------
        public function getStage():Stage{
            return stage;    
        }

//----------------------------------------------------------------------
        public function getInit():Init{
            return init;    
        }

//---------------------------------------------------------------------------------------
// Private
//---------------------------------------------------------------------------------------
        private function mainAddedToStage(e:Event):void{
            stage=this.stage;
            stage.showDefaultContextMenu=false;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.quality=StageQuality.LOW;
            stage.stageFocusRect=false;

            __parent=this.root;
            
            init=new Init();
        }


//---------------------------------------------------------------------------------------
    }
}

Hopefully this should be fairly straight forward ( I did actually grab it from somewhere else when looking for an as3 version which matched what I was doing in as2, so sorry original author, I can't tell anymore what's yours and what's mine ). We're basically waiting around until this instance is added to the stage ( If you try and read some properties before it's technically been created then you're going to get errors. ) and then running the mainAddedToStage method. Importantly we have some getter methods set up here, as we need them ( More later ). This is our document class, and as such it has a "direct" link with the swf ( For want of a better term ). From now on throughout every other class, any reference to stage or Main is obtained from this class.
The very last line you'll see we create a new instance of the Init class ( init=new Init(); ), so let's check that class out.

package Classes {
    import flash.display.DisplayObject;
    import flash.display.Sprite;
    import flash.display.Stage;

    public class Init {
//---------------------------------------------------------------------------------------
// Properties
//---------------------------------------------------------------------------------------
        private var gameController:GameController;
        private var attract:Attract;
        private var soundHandler:SoundHandler;
        
//------------------------------------------------
// System
//------------------------------------------------
        private var main:Main;
        private var mainMovie:DisplayObject;
        private var stage:Stage;
        
//---------------------------------------------------------------------------------------
//Constructor
//---------------------------------------------------------------------------------------
        public function Init(){
            main=Main.getInstance();
            mainMovie=main.getMainMovie();
            stage=main.getStage();

            soundHandler=new SoundHandler();
           
            gameController=new GameController();
            attract=new Attract();
        }

//---------------------------------------------------------------------------------------
// Public
//---------------------------------------------------------------------------------------
        public function toString():String {
            return "Init";
        }        

//---------------------------------------------------------------------------------------
// Getters
//---------------------------------------------------------------------------------------
        public function getAttract():Attract{
            return attract;
        }

//---------------------------------------------------------------------------------------
        public function getGameController():GameController{
            return gameController;
        }

//---------------------------------------------------------------------------------------
        public function getSoundHandler():SoundHandler{
            return soundHandler;
        }

//---------------------------------------------------------------------------------------
    }
}

This again is a bit of a nothingy class. In theory it could be shoved into the Main class with no real harm, the reason I don't is pure lazyness. I like being able to copy the Main class to every new project without having to think about it, i.e aside from the [swf] tag I never have to alter it. It just feels cleaner having that first class do very little.

If you look at our Init class you'll see we just create instances of each class we need ( Refer to our cheapo diagram to help clarify ), and set up some getter methods again ( Just to clarify, a method is exactly the same as a Function, it's just that if you use a function in oop it's called a method instead. I don't know why either ), so other classes can get a reference to these instance's if they need to.

How do I decide which classes sit on which row of the hierarchy ? Main is our document class, so he's at the top and doesn't really do much. Init is Main's love child, and doesn't do much either, he's just creating the actual game classes.
The next row is more interesting. Attract is our front-end. It deals with the title screen, the game over screen, hi-score entry if the game supports it, instructions etc. Basically everything that happens before starting the game and after the game has finished.
Let's jump over to SoundHandler. This is just what it says. It's here because it's used by both Attract and GameController, as both need to have sounds. GameController is a simple class like Init, it handles the creation of all the child classes needed for the game ( Check the diagram ).

Let me try and rationalise why Attract, GameController, SoundHandler are all on the same row, in effect why they're equal to each other. We've already established that Attract and GameController need to be aware of the SoundHandler class as both need sounds. In the grand scheme of things, the Attract class doesn't really need to know about GameController ( Remember Attract is everything but the actual game ) and conversely the GameController really doesn't give a crap about Attract. If one of these classes is working, then the other isn't doing anything, so it makes sense to me that they're on the same row.
Does that mean they never need to chat to each other ? No, but it's at very key points. For example, when the player presses the "Play Game" button in Attract, we kill off all the Attract mode things and then call startGame() method in GameController.

Now we come to something cool. Quite a few times I've seen people moving over to oop, and it's all going well, until they need a reference to a different class. How the hell do we get the reference we need ? No one wants to pass a reference to a class via a constructor, as that's just messy and nasty and really easy to screw up, and it's not like we can be old school and use _root.myMethod(); when we're oop gods.

Notice all my constructors are the same, eg,

//------------------------------------------------
// System
//------------------------------------------------
        private var main:Main;
        private var mainMovie:DisplayObject;
        private var stage:Stage;
        
//---------------------------------------------------------------------------------------
//Constructor
//---------------------------------------------------------------------------------------
        public function GameController(){
            main=Main.getInstance();
            mainMovie=main.getMainMovie();
            stage=main.getStage();
        }

We get a reference to our document class, Main and store it in our local var main. We also store away a reference to our mainMovie ( To be honest I don't think I've used that ref. in as3 yet, it's just a throw back to my as2 code, but I'm a creature of habit so it'll stay there 'til as4 ) and the Stage.

So this is the GameController class, and it's game over, so we want to call the Attract class as he deals with that. This is how we get our reference:

main.getInit().getAttract().gameOver();

Check back with our Main class code up there, see getInit() in the getters section ? It returns a reference to our Init instance. Then look at the Init getters, getAttract() gives us our instance of Attract, and from there we're just calling the method gameOver in the Attract class.
Don't worry if this doesn't make sense straight away, it's quite a bit to get your head around in one go. Basically so long as we have a reference to Main in any class, we can get a reference to any other class no matter how far away from the callee class we are. References aren't a pain in the arse anymore, they're as simple as this.

You may be thinking, how the hell am I going to remember all those getOurInstanceName() method calls. Auto-completion. Flex does all this for you so it's never an issue ( And I'm sure Flash Develop does the same ). I don't know about the Flash IDE, I really don't hold much faith in it doing it, so now may be the time to install Flash Develop and have a play with that.

See we've got the basics of oop hierarchy covered, and I've not had to slip into terms like singleton and composition. Feel free to google both terms, see what they actually mean, and hopefully when you read the flowery descriptions you'll realise that you already get them as we've covered them here.

As always feel free to fire over questions or point out glaring errors in what I've done. Like I said all my games pretty much follow this pattern, which makes sharing code between projects a lot easier plus I'm not having to think about how classes are inter-connected. I'm not suggesting you just blindly copy what I've done, but perhaps plan out your next game using some simple flowchart boxes so you can see where classes should be connected and where it'll be a waste of time to do so.

Squize.

Wednesday, July 01, 2009 1:27:56 AM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [12]  |  Trackback
 Tuesday, June 30, 2009
Our mate Chris has been working away on his first Unity3D powered iPhone game for a little while, and now it's available for free on the iPhone store his mind turned to pimping, and our's to getting an interview so we could pad things out a little without just looking cheap.

snowball_title_screen.png

What I do love is the way Chris just ignores the shit in my questions and just answers the core point without rising to my bait, like I'm 12 and best just ignored.

"How did you find moving from Flash to Unity ? They seem to share a common core, but are different enough to make life interesting. How was it for you ( Darling ) ?"

In some ways it hardly felt different at all, as if they were from the same software family, Unity's version of Javascript is so close to Actionscript (for example when working on the Mac now, I even use Unity's code editor 'Unitron' for my actionscript coding) but when it came to structuring the game it really is very different.
Actually building game mechanics, levels, controls etc is really very intuitive in Unity, however there doesn't seem to be any one agreed way on storing things like player data, global game settings.
The way I ended up doing it all is with a 'gameObject' that doesn't get destroyed when moving between scenes (but this
in itself causes problems when testing then, as you don't have to test from the opening scene, and hence the gameObject hasn't been made yet.)
If someone knows a better way way please do tell me  :)
"iPhone dev via Unity, sex or a drunken wank ( Maybe with tears. Why did she leave, why ? )"

Considering what it does I really don't see how it could be any easier. It gets slightly complicated when you finally move the project over to Xcode, but then Xcode is complicated and that's nowt to do with Unity, is it wrong of me to think that maybe Apple have purposefully made this bit hard to keep the kids out?
It really is very complicated and parts of it would try the patience of a Saint, but as I said this isn't anything to do with Unity.
Maybe someone out there can let me know, is it always this convoluted when dev-ing for consoles? Are there just always weird things you have to do due to copy protection / code signing?

snowball_dev_shot.jpg


"Tell us about going through Apples hoops to get the game on the store, was it just like a great big hug, or more a spit in the eye ?"

It wasn't as bad as I thought it would be truth be told. From first submission to being live in the App Store took around 14 days. We had one
build sent back to us, as we weren't making it clear that the high score table was storing the user's data remotely and also we hadn't specifically requested the users permission to access the internet.
One amazing achievement is though that we have not received one crash report yet, which is testament to how awesome I really am (or that maybe I am working on a lovely high level piece of industry quality middleware with some brilliant engineers...hmm it's probably my awesomeness now that I think about it.)

IMG_0004.PNG

"It's early days yet, but how's the game doing ? Any sort of trend apparent or is it getting lost in the zillion new releases every day ?"

It's done well for what it is, which is a first game, proof of concept. It spent around one week in the top 30 free arcade games and is now in the top 60 or so. It's been installed around 12,000 times and we've had some lovely reviews off people (many of whom commented that is it better and easier to control the Super Monkey Ball on the iPhone).
One interesting point is that we may have got more installs had we charged. This is pure speculation on my behalf, but something I didn't realise is that many of the very popular review sites and magazines for iPhone simply won't cover free games, so even by charging only 59p or something we could conceivably got in pocketGamer, Edge, RetroGamer etc.  So I guess we will be testing my theory on this for
Snowball's Chance in Hell 2  :)

"If badgers had guns, do you think they'd rob post offices ?"

No they'd rob Mash Potato factories.

I hadn't even considered that, damn he's on intellectual fire.

Now you're wet for the game, here's the all important link http://bit.ly/kill5Snowball

Never one to miss the chance to spread the word Chris told me about Kill5's competition. Let's face it, it's not a competition, it's a bribe, but fuck it, who wouldn't want an iPod Touch ?
Read all about it here, http://www.kill5.com/competition/ but come on, I've kinda earned the iPod with this article, so really don't expect to win.
( What should happen if by some fluke I do win ? Everyone is going to think we're big cheaty cheats, I've screwed myself now haven't I ).

A big thanks to Chris for taking the time to do this interview. I'm sure if anyone has some follow up questions he'll be around to tackle them in the comments.

Squize.

Tuesday, June 30, 2009 1:03:16 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [2]  |  Trackback
 Monday, June 29, 2009
This is part 2 of my collection of articles that'll deal with the theory (and the actual creation) of random dynamic levels for a (space)game. In part one we created a damn pretty maze and in part two we're going to modify it a good deal.

If you take a look at part one's output you'll notice that the code generates a pretty random maze. And there we got out first drawback: it's pretty darn random, way to random to assemble a man made structure and not quite what we would expect a spacestation / space ship to look like.

So the first modification I'm going to add will be a method that can reduce the randomness of the maze.

Part 2 - part 1 - making something not that random

My idea is to qualify the randomness by a percentage value, so a random factor of 0 will give you long straight passages that only change direction if the need to (random at that), while using a value of 100 the method will never (as far as it possible) return the same direction twice.

Of course that tiny little addition causes a lot of fuzz and requieres to rewrite a part of the core maze generator function. In part 1 I used a method to get all surrounding cells of a given point, but in order to use the direction modifier we need to use directions instead.

          //... skipped

          while (iCellCount < iTotalCells) {
                
                // get neighbor cells ...
                aCellDirections = myDungeon.getPossibleDirections(pCurrentCell);
                
                // set the cell
                if (aCellDirections.length != 0) {
                    
                    /* old way no direction modification used
                    iRndCell = rnd.Range(0, (aCellNeighbors.length - 1));
                    iRndDir = Dir.getDirFromPoint(pCurrentCell, aCellNeighbors[iRndCell]);
                    */

                    iRndDir = this.getFactoredRandomDir(iLastDir, aCellDirections, iDirChange);
                    pNextCell = myDungeon.getNextPos(pCurrentCell, iRndDir);
                    iLastDir = iRndDir;
                    
                    // remove walls
                    myDungeon.cell(pCurrentCell).setWall (iRndDir, WallType.OPEN);
                    // old way: myDungeon.cell(aCellNeighbors[iRndCell]).setWall(Dir.getOppositeDir(iRndDir), WallType.OPEN);
                    myDungeon.cell(pNextCell).setWall(Dir.getOppositeDir(iRndDir), WallType.OPEN);
                    
                    // store for later use ...
                    aCellStack.push(new Point(pCurrentCell.x, pCurrentCell.y));
                    // old way: pCurrentCell = new Point(aCellNeighbors[iRndCell].x, aCellNeighbors[iRndCell].y);
                    pCurrentCell = new Point(pNextCell.x, pNextCell.y);
                    
                    iCellCount++;
                } else {
                    pPopCell = aCellStack.pop();
                    pCurrentCell = new Point(pPopCell.x, pPopCell.y);
                }
                
            } // while

Some new variables in there: iLastDir (so we can keep track of the last direction used), pNextCell (a point that stores the next cell, basically just a temp. variable), iRndCell has been removed and aCellNeighbours has been renamed to aCellDirections ...

There are two new methdods: getPossibleDirections and getFactoredRandomDir. The first one returns an array that just contains directions that can be used (ie. cells that have not been visited yet), directions are simply stored as 0=North, 1=East and so one (I've encapsulated them into a Dir class to make it easier to read). The second method is a neat example how to make things overly complicated ...

        private function getFactoredRandomDir (iLastDir:int, aListDir:Array, iFactor:int = 50):int {
            
            var rnd:MersenneTwister = MersenneTwister.getInstance();
            var bChangeDir:Boolean = (rnd.Range(0, 99) < iFactor);
            
            var iReturn:int = iLastDir;
            
            // the last used dir is not in the list of possible new directions, so we need to pick a random one ...
            if (aListDir.toString().lastIndexOf(iLastDir.toString()) == -1) {
                iReturn = aListDir[rnd.Range(0, (aListDir.length -1))];
            } else {
                
                // we must change direction AND have at least 2 choices
                if (aListDir.length > 1) {
                    
                    if (bChangeDir) {
                        while (iReturn == iLastDir) {
                            iReturn = aListDir[rnd.Range(0, (aListDir.length -1))];
                        }
                    }
                    
                } else {
                    // just pick what's left ...
                    iReturn = aListDir[0];
                }
                
            }
            
            return iReturn;
            
            
        }


AS3 arrays (in CS3) don't have the nice method I know from c#: contains which would have been oh so easy to use here. I toyed for a fraction of a second with the idea to use a loop to check if a given value would be in an array, but then decided to go ... quick and dirty and use toString and lastIndexOf instead.

The code above is quite easy, so I only do a quick run through it...
- decide if we need to apply a direction change
- if we need to, check if the last dir is in the list of possible dirs, if not just pic a random new (this applies to both states: need to change and keep direction)
- otherwise just pick a random dir until it's not equal the last dir used

That's it.

Running the test app with different values seems to produce the desired results:
0% produces the most possible straight halls,
50% produces somewhat random halls
100% produces a maze with no straight hall at all.

Part 2 - part 2 - still way to much filled space ...

Looking at the maze reveals that there are no free spaces in it, of course we could just paint rooms over it, but I doubt it'll look like what I have in mind.
Randomly removing cells from the map is no option (even if we do check if we would just block a passage), but what about removing cells that just end the passage (ie: dead ends).
Looking at the maze again, it seems that we have (depending on the randomness of direction changes) a lot of them, so our next task would be to find those dead ends and remove them. The first "problem" that comes to me is that each time we remove dead ends, we'd create new ones. In order to clean up the map we only run the "removDeadEnds" methods a couple of times and we're done - right?

Not quite.

If we choose some unlucky values, it might happen that we kill the whole maze and that's something we don't want at all.

I decided to use a percentage of TotalCells that I want to be removed, so if we use 50%, the method should remove half of all available cells.

        public function removeDeadEnds (myDungeon:Dungeon, iRemoveDeadEnd:int = 20):Dungeon {
            
            var rnd:MersenneTwister = MersenneTwister.getInstance();
            
            var i:int;
            var j:uint;
            var iDir:int;
            var iRndCell:int;
            
            var iDeadEndsToRemove:int = Math.ceil((myDungeon.iWidth * myDungeon.iHeight) * iRemoveDeadEnd / 100);
            var iDeadEndCount:int = 0;
            
            var bExit:Boolean = false;
            
            var aTmp:Array;
            
            // the worst case may only return one dead end per run, so
            // to be sure we run it as many times as we may max need
            for (i = 0; i < iDeadEndsToRemove; i++) {
                
                aTmp = myDungeon.getDeadEnds();
                
                if (aTmp.length > 0 && !bExit) {

                    while (aTmp.length > 0) {
                    
                        // this is to make sure that the cells are somewhat even
                        // distributed if we do not use the whole lot
                        iRndCell = rnd.Range(0, (aTmp.length - 1));
                        iDir = myDungeon.cell(aTmp[iRndCell]).getDeadEndDir();
                        
                        myDungeon.cell(myDungeon.getNextPos(aTmp[iRndCell], iDir)).setWall(Dir.getOppositeDir(iDir), WallType.WALL);
                        myDungeon.cell(aTmp[iRndCell]).setWalls();
                        
                        aTmp.splice(iRndCell, 1);
                        
                        if (++iDeadEndCount >= iDeadEndsToRemove) {
                            bExit = true;
                            break;
                        }
                        
                    }
                } else {
                    break;
                }
                
            }
            
            return myDungeon;
            
        }


The comments should explain quite well what's going on in there. Only thing to mention is that I pic random dead ends if there are more available dead ends than cells to remove.

Compile and test ... and viola well done for today. :)

(I must admid it took longer to type all that than to code, so I had a bit of spare time left and coded something alse ;) )

I think that is enough for today, you can see the result (and from the upcoming articles, too) Random Dynamic Level Creation Test page (or here if the server is down).

nGFX

Monday, June 29, 2009 2:34:28 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Wednesday, June 24, 2009
After a good while of non-techy pimpings I decided to go the x++ route and describe the process of diving into a new game ...

(CE is again on hold due to some gameplay issues I found during testplays - oh well)

There is no name to the game yet, but I can say as much as it will feature random dynamic level creation (as used in Diablo 1 for example), sci-fi themed, using RPG elements and use Unity (though the levels created will look quite different to Diablo, but the idea is the same).
I want to have random levels because that would add to the replay value of the game. I want a single game to last between 15 and 45 minutes. You should be able to start playing and kill the end-boss in that time. After that you should be able just play again, but with different set of maps ...

But to get things rolling a lot quicker I wanted to rapid prototype my ideas using flash/AS3 and then port it to c#.
The reason for this is quite simple: output. In order to "see" what the level will look like without having to worry about how to display them (ie. place 3d walls, create the assets). With using flash i can just grab the data from the generator classes and use the drawing api to quickly throw out a few lines to show the generated data.

Let's dive straight in.

Part 1 - part 1: To cell or to tile ... and is there anything we need before that?

Before I started I thought that it would be nice to move between maps (in case you thought you forgot something), to do so there needs to be a way to store the maps ... I thought of 2 methods:
a) store all visited maps
b) make them reproduceable

I prefer the later one.

So instead of using some built in random number generator I decided to use my "own" that takes a seed and the produces the same set of random numbers when using that seed - perfect.
I found some old AS1 source of some older rnd gen that I could have ported but a quick search showed that there are some more powerfull ones. After bit of research I decided to go with the Mersenne Twister algorithm. As I was too lazy to see if there was an AS3 port, I wrote my own implementation, though you could use any rnd method you want.

The next one was a bit tricky: cell based or tile based?
Tiles are easy to use and to handle, but they are limited to a single spot and mostly do only have a single "state", ie. you can walk on them or not. This might be ok in most cases but for what I have in mind they are too limited.

A cell in my case is a tile with 4 walls (north, east, south and west), if all 4 walls are set, the cell is "closed" ie. a solid rock in a clasical dungeon. The cell also stors a single integer value (so based on it's useage I could store an index in it.
Here is the code for the cell:

package com.gamingyourway.Dungeon {
    
    /**
     * Cell datatype
     * @version 2009 06 24
     * @author nGFX
     */

    public class Cell {
        
        public static const WALL:int = 0;
        public static const OPEN:int = 1;
                
        private var _aWall:Array;    // array of values ... 0=empty ...
        private var _iValue:int;    // stores a single value, ie. room num
        private var _bVisited:Boolean;    // has cell been visited
        private var _bCorridor:Boolean;    // is cell a corridor
        
        
        public function get aWall ():Array { return this._aWall; }
        public function set aWall (value:Array):void { this._aWall = value; }
        
        public function get iValue ():int { return this._iValue; }
        public function set iValue (value:int):void { this._iValue = value; }
        
        public function get bVisited ():Boolean { return this._bVisited; }
        public function set bVisited (value:Boolean):void { this._bVisited = value; }
        
        public function get bCorridor ():Boolean { return this._bCorridor; }
        public function set bCorridor (value:Boolean):void { this._bCorridor = value; }
        
        public function get wallCount ():int {
            
            var i:uint;
            var iCount:int = 0;
            
            for (i = 0; i < this._aWall.length; i++) {
                if (this._aWall[i] == 0) iCount++;
            }
            
            return iCount;
            
        }
        
        public function get isDeadEnd ():Boolean { return (this.wallCount == 3); }
        public function get isUnused ():Boolean { return (this.wallCount == 4); }
        
        /**
         * Creates a new empty (ie. all walls set) cells
         * @param    iValue    used to stor a single bit of info, ie. room num
         */

        public function Cell (iValue:int = 0) {
        
            this._aWall = [0, 0, 0, 0];
            this._iValue = iValue;
            this._bVisited = false;
            this._bCorridor = false;
            
        }
        
        /**
         * sets a single wall
         * @param    iDir    Direction of the wall
         * @param    iWall    value of the wall, 0 is a solid wall, any other value makes it "open"
         */

        public function setWall (iDir:int, iWall:int = 0):void {
            
            this._aWall[iDir] = iWall;
            
        }
        
        /**
         * return the value if the wall in iDIr
         * @param    iDir    direction of the wall to get
         * @return    value of the wall
         */

        public function getWall (iDir:int):uint {
            
            return this._aWall[iDir];
            
        }
        
        /**
         * shortcut for testing if there is a closed wall in iDir
         * @param    iDir    direction to test
         * @return    true if there is a wall
         */

        public function hasWall (iDir:int):Boolean {
            
            return (this._aWall[iDir] == 0);
            
        }
        
        /**
         * if the cell is a dead end, return the direction of the opening
         * @return    the direction of the opening
         */

        public function getDeadEndDir ():int {
            
            var iReturn:int = -1; // not a dead end
            
            if (isDeadEnd) {
                
                if (this._aWall[Dir.NORTH] != 0) iReturn = Dir.NORTH;
                if (this._aWall[Dir.EAST] != 0) iReturn = Dir.EAST;
                if (this._aWall[Dir.SOUTH] != 0) iReturn = Dir.SOUTH;
                if (this._aWall[Dir.WEST] != 0) iReturn = Dir.WEST;
                
            }
            
            return iReturn;
            
        }
        
        /**
         * returns a string representation of the cell
         * @return    a string for the falls of this cell
         */

        public function toString ():String {
            
            var i:uint;
            var strReturn:String = "";
            
            for (i = 0; i < this._aWall.length; i++) {
                strReturn += this._aWall[i].toString();
            }
            
            return strReturn;
            
        }
        
        
    }
    
}


Part 1 - part 2 - Storage and creation

To store the maps generated I wrote a simple Mapa datatype, it'll store a 2d array of cells along with some very basic methods to deal with the data.
The map type also stores width and height in an rectangle, to have an easy way to check if a point lies within the boundaries of the map.
Aditional methods so far:

hasCellInDir (pPos:Point, iDir:uint):Boolean
getNextPos (pPos:Point, iDir:uint):Point
getSurroundingCells (pPos:Point, bUsed:Boolean = false):Array


To create a map (let's call it dungeon for the sake of easiness) I didn't include the methods need to create a dungeon in the map class, instead I wrote a DungeonGenerator class, that returns a filled map class. This way I can mess around with the creation process without messing with the map class.

Part 1 - part 3 - Let's start with a simple maze ...

The most simple representation of a dungeon I can think of is a maze. Mazes are incredibly easy to create and they work oh so well with cells.

The walkthrough to create a maze:
1. create a map of "solid" cells
2. pick a random solid cell as starting point
3. get surrounding solid cells and pick a random one
4. knock the walls between these cells, store the "old" cell in a stack for later use
5. use the cell picked in 3 as new starting point and start over
6. if the current cell has no solid neighbours, pop one from the stack
7. repeat until there are no more solid cells


Easy, eh?

package com.gamingyourway.Dungeon {
    import de.drygoods.Random.MersenneTwister;
    import flash.geom.Point;
    
    /**
     * Dungeon generator
     * @version 2009 06 24
     * @author nGFX
     */
    public class DungeonGenerator {
        
        private var _Dungeon:Dungeon;
        private var _rnd:MersenneTwister;
        
        public function DungeonGenerator(iWidth:int, iHeight:int) {
            
            this._Dungeon = new Dungeon(iWidth, iHeight);
            
            this._rnd = MersenneTwister.getInstance();
            
        }
        
        public function createMaze (iDirChange:int = 100):Dungeon {
            
            var aCellStack:Array = new Array();
            var aCellNeighbors:Array;
            
            var iTotalCells:int = this._Dungeon.iWidth * this._Dungeon.iHeight;
            var iCellCount:int = 1;
            var iRndCell:int;
            var iRndDir:int;
            
            var pCurrentCell:Point = new Point(this._rnd.Range(0, this._Dungeon.iWidth -1), this._rnd.Range(0, this._Dungeon.iHeight -1));
            var pPopCell:Point;
            
            while (iCellCount < iTotalCells) {
                
                // get neighbor cells ...
                aCellNeighbors = this._Dungeon.getSurroundingCells(pCurrentCell);
                
                // set the cell
                if (aCellNeighbors.length != 0) {
                    
                    iRndCell = this._rnd.Range(0, (aCellNeighbors.length - 1));
                    iRndDir = Dir.getDirFromPoint(pCurrentCell, aCellNeighbors[iRndCell]);
                    
                    // remove walls
                    this._Dungeon.cell(pCurrentCell).setWall (iRndDir, 1);
                    this._Dungeon.cell(aCellNeighbors[iRndCell]).setWall(Dir.getOppositeDir(iRndDir), 1);
                    
                    // store for later use ...
                    aCellStack.push(new Point(pCurrentCell.x, pCurrentCell.y));
                    pCurrentCell = new Point(aCellNeighbors[iRndCell].x, aCellNeighbors[iRndCell].y);
                    
                    iCellCount++;
                } else {
                    pPopCell = aCellStack.pop();
                    pCurrentCell = new Point(pPopCell.x, pPopCell.y);
                }
                
            } // while
            
            
            return this._Dungeon;
            
        }
        
    }
    
}


The code of the dungeon generator ... for now only with the maze creation in it.
Note that the variable iDirChange is currently not used, but I'll go over it in the 2nd part of this article.

I think that is enough for today, you can see the result (and from the upcoming articles, too) Random Dynamic Level Creation Test page (or here).

See you next time when I add some direction modifications and take care of dead ends ...

nGFX


Wednesday, June 24, 2009 3:02:34 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [7]  |  Trackback
 Wednesday, June 17, 2009
Perhaps 'cause it's late, and I'm tired, and I'm coming down from quite a hellish crunch ( All the games got there in time, and the client is pleased. Just thought I should share the good news along with the moans and gripes ), but something is bugging me.

Mike Chambers, well known Flash community facing guy at Adobe, has posted "What new game APIs do you want in the Flash Player ?".

Fantastic!

Why do I feel the need to be churlish about this, I mean it's great news, isn't it ? A chance to air our views to someone whose in a position to push forward ideas to the roadmap.

"I have been learning some game development lately, and building my first game... I think game development and deployment are some of the real strengths of the Flash player, but ones which we haven’t specifically focused on in a while... While working on my game, there were a couple of things I needed to do where additional player APIs could have made the development easier... So, what APIs would you like to see that would make game development easier."

( That's the gist of the post, but please take a minute to read it all ).

Personally, I'd like to see all the things that so many game developers have been asking for since Flash 5. Mike mentions how handy it would be to have a built in pixel perfect hitTest. Surely everyone one reading this right now has been thinking that for years ? Has no one ever requested that feature ?

Why have all the feature requests fallen on deaf ears before ? Flash has been geared towards RIA's for years, with a recent glance at 3D as Away3D et al have helped fill in a short fall with the player, along with the huge ( And really successful ) push to own web video.

But games have been left out in the cold. They're treated like they're almost a happy side effect of the Flash player, that it's not really a real use of Flash ( Noticed that very few of the really high profile Flash developers make games ? Some of them touch on game related mechanics, and do it really well, but actual complete games are very few and far between. I'm sure if they did they would be vocal about the shortfalls in the API and help to have forced a change sooner. Sound got a kick up the arse using a similar approach ).
And yet, GameJacket had a stat that 28% of internet traffic was Flash games ( I can't provide a link for obvious reasons ). The Flash Forwards have a game category. Until a couple of years ago BAFTA did too ( That's now being merged with console games, and in all fairness I can't see Desktop Tower Defence giving Call of Duty a run for it's money ). Millions of people play Flash games, and talk about them, every day
There is a knowledge and interest of Flash gaming, with huge budgets for them, outside of the "Suck and Fuck Street Racing"s.

So why has it taken until now for it to be recognised by Adobe ? Would it really have taken so much effort to not package yet another fucking scroll bar component and give us a hi-score table component just once ? I know there's an excellent one from Mochi, but we're talking first party support here.

Yes to some extent I am being churlish. In effect I'm bitching about Adobe looking to make all our jobs that little bit better, it's just that does it really only take one employee at Adobe to notice the shortfall for things to happen ?

( And yes before you ask I am a bit of a hypocrite as I've never filled in a feature list request for Flash. Maybe all of us who haven't have just got ourselves to blame that we're going to have to wait 'til F11 before getting the sugar ).

Squize.

Wednesday, June 17, 2009 12:21:54 AM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [12]  |  Trackback
 Monday, March 23, 2009
Hi all.

Back on coding CE again (at least for a few hours today) after spending a good deal of time coding and designing the backend for MYW, writing a tiny versatile CMS and doing some 3d for X.

So today I'm  going to ask myself why the hell I have done a few things in CE the way I did them (I bet you are a lot wiser now).

Let's raise the question if it is worth to add the extra amount of work needed to draw a hard line between the game's "engine" and the game's UI - for your average flash game.

You may have noticed that neither Squize nor me tend to make out lives overly easy when it comes to games, for some odd reason we both tend to try to give out very best for each and every game (even if it is a pain in the back) - well call that stupid.

Give me a good reason to split game and game (play) UI ...
The best reason I can come up with is: reusability, and it is also the least used one.

In most cases I can come up with there seems to be no reason to really split things, because the game is a one-of-a-kind thing. Even for games that share a good deal of similarites (like Wintertales and LogiMotion), a whole lot of things need to be rewritten in order to reuse the engine.

That leaves the reusability inside a single game. !?

WTH?

Inside a single game? Yep!

A good deal of our games either uses an ingame editor (although not usable by the player)  or uses an external editor to generate the level data. Mostly, but not always they share the same visuals. For instance the editor for Logimotion uses smaller tiles than the game itself (so have room for the tools and don't have to scroll the map). That is a good reason to split things between the UI and the "engine".
Another good reason is when you have a stupid designer and you just code - you know those guys tend to be smart and change the size of the assets as often as you should change your underwear.

So why question that and not do it all the time?

Well, it takes a good deal more planing to really split things up. in an ideal world, the "game" knows nothing about the UI, but it still has to control it (ie. update the score, display infos). In my case this is done using callbacks.
A good example might be a game we did (but still isn't playable online): CC

cc_game_00.jpg
(CC game, using 40x40 tiles)

cc_editor_00.jpg
(CC editor, using 32x32 tiles)

As you're meant to be able to play the game inside the editor (without leaving it), the engine had to cope with different tile sizes and environments.

So whenever the game needs to comunicate with its surroundings I provide a callback method, if I would have made it "the right" way, I should have used an interface for that, but ... hell you can overdo it too.

To make it easier and not having an endless number of callback methds I used only a few and gave them params (which are stored in the game's class as constants: like:

public static const UPDATEUI_INFO:uint = 0;
public static const UPDATEUI_BTNPLAY:uint = 1;
public static const UPDATEUI_ITEM:uint = 2;
public static const UPDATEUI_WIN:uint = 3;

Whenever you finish a level, the game would just call the callback provided for UI updates and pass the parameter needed.

And is it really worth the extra work?
Not always.

I like to spend that extra piece of work for games that require and editor or might have parts in it that seem to be a good start for reusing it in a second game. Sometimes you notice halfway through the project that you need to change something to make the game work again (ie. different tile size, or different UI), sometimes (like I did for CE) you notice that the game will be a one of and you cause yourself a good deal of fuzz for "nice code" only.

Well, lets get back coding CE.

nGFX


Monday, March 23, 2009 11:18:59 AM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, January 15, 2009
What has been done on Calisto Eclipse so far:

  • the main menu is done, all the neat rollover effects are in place
  • you can reach the two highscore screens (one for the action and one for story mode), alas the backend for that isn't working yet
  • the medal screen is in place and the medals are defined, same as above the backend isn't done yet (more on that later)
  • parts of the API for handling medals and scores are layed out (yet again ...)
  • the game working is layed out and waits to be coded
What's need doing (in no particular oder):
  • transition between the menu screens and the game
  • the game :)
  • finish the API for medals and highscores
  • the backend for medals and highscore (oh there's so fucking much to do on this bugger, but maybe I can give away some more infos soon)
  • ingame help
  • ingame newsfeed reader
  • even more backend stuff ...
  • even more of that oh so boring backend stuff ...
what a boring post. damn.

I post an image next time, promissed.

nGFX

Wednesday, January 14, 2009 11:05:22 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, January 08, 2009
Hi,
long time no post (but Squize has pretty much made it needless).

What happened so far ...

After a few days off from nearly everything except gaming (on my new shiny plasma) I finally got back to work on Calisto Eclipse. I decided to go the hard way and rewrite most of the menu code (before I even started coding on the game) and ended up with something I might just call the "ScreenFramework".

Basically I usually use the same style for coding:
1st there's a Singleton main controler class through which I can access all the low level stuff, because I hate having to post around references or "crosslink" classes.
This class also provides access to the ScreenFramework (name might change to something catchy), the SF class allows an easy way of switching screens using a predifined "transition".

So to get from "mcScreenMenu" (currently active) to "mcScreenMedal", it's just this (pseudo code):
SF.showScreen("mcScreenMedal", [optional transition code to use]);

... attach the new screen, perform transition, remove the old screen

All screens are "self contained" so before removing them I call the "dispose" method (did I mention that all screens use the SimpleScreen interface?), which cleans the mess the screen has caused in memory and might set a few things in the controler class.

As Calisto is also the testbed for another project we have been tinkering with for a while, it's not just developing the game but also a lot of backend server stuff, which is a pitty, because I really would like to share a good deal more of the development process for CE (although, after having the screen handling nailed I might just show that for the sake of it).

nGFX


Thursday, January 08, 2009 9:31:38 AM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [3]  |  Trackback
 Wednesday, January 07, 2009
Hi,

More in the world of X++

The final power-up, the pulse weapon, is in now. It's a big old powerful shot, slow to move, slow to reload, but two hits from that and anything is dead.
To try and make it bigger and give it a bit more wow, I've used the particles playfield too. The particles are just little images ( Not pixels, they look too small, and it's something a lot of Flash GWars style games do, either that or they add a big ol' blur effect onto them. Neither being very nice ) which are blitted into a canvas bitmap.
Every couple of frames I run a colorMatrixFilter on that bitmap canvas to fade the alpha down, all straight forward stuff we've all been doing since F8 came along.

With the pulse I just draw() it's image into the canvas bitmap so it creates a trail / thickens it up ( For want of a better term ). Draw() is a bit costly, but I'm only ever running at most 10 pulse bullets at once ( They were always going to be slow to reload, that's why I figured I could get away with doing this extra trail effect ).
I'm really happy with it, it's in keeping with the very glowy nature of the game. BlendMode.ADD is the best thing to happen to Flash for a long time.

Once that was all in and working I did even more tweaking to the difficulty curve, the flockers now get nastier as you go, which is based both on the current level and the number of lives you have left ( If you're not doing so well there's no need to make it even harder ).

Then back to the power-ups again, and the space bar now swaps between them, which works a treat.

It's all going to plan so far, and seeing how we're on what, around 12 ( Full days ) development time, it's pretty good. It'll be nice to add the final baddie type ( Did someone say bullet hell ? ) and then the biggest thing should be the sound, which I'm a little concerned about 'cause there's a lot of things going on, and it'll be easy to just overwhelm the player with sound and make it really jar. Some thought is going to need to go into that.
From there we're looking at presentational issues and then bugs, love and play testing.

Squize.

Wednesday, January 07, 2009 1:24:24 AM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [14]  |  Trackback
 Tuesday, January 06, 2009
Things didn't work out as planned today, and I've spent most of the day hitting X again.

I think this is going to be pretty brief as it's just gone 2:50 am and I'm pretty dead on my feet. Main changes are the asteroids now use the bitmap technique as mentioned in the last blog ( Not final images, and the way they animate shows up the circle to circle collision checks quite badly, the final images will animate in such a way as to hide that ), the baddies drop an icon which can be shot to select your power-up ( Again placeholders. The final images will be a lot more colour coded to make it much easier ).

I've decided after a long think today, and some great ideas posted in yesterdays comments ( Vex, didn't reply there mate, but I really liked your timer based idea, but I think for a web game I have to strip away complications as much as possible. Too tired to go into depth right now why that idea could be complicated, bug me in the comments if you really want me to justify it  ), I've opted for something quite straight forward.
A power-up icon is dropped after killing 20 baddies. You can shoot it to change it to a power-up you want, and then collect it. Every time you collect one you boost it's power ( Shown by the 3 new indicators at the bottom left ). Tomorrow ( Today ) I'll add the option to press space to change what power-up you're currently using ( Space was being reserved for a possible smart bomb, but I figure the player is going to have enough fire power as it is ).
Also the pulse weapon hasn't been coded yet, so collecting the icon with a little star on will break things. Not every build I post was going to be nice and neat I'm afraid.

I've also played with the difficulty curve a bit, and it's coming together a lot more. I've got at least one more baddie type in mind, maybe two ( And a third has just come to mind, but I've got to draw a line somewhere ), and then I should really be able to have a big push to finalise when things are triggered, how many shots they take to kill, how much energy you lose etc.
Also the asteroids themselves may drop point based collectables, as there's no combo system in this game, and I do want to give the player an incentive to move rather than just spin on the spot.

Despite my bloodshot eyes it's coming together nicely now, I'm finally starting to get a real feel for how I want it to play. A couple more days of giving it a really big push and we should be looking at something a lot more final.

Squize.

Tuesday, January 06, 2009 2:51:39 AM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [4]  |  Trackback
 Sunday, January 04, 2009
I'm starting a reskin of the bowling game I was working on last year ( Working on a reskin of a game which isn't even live yet, that's weird ) tomorrow, the holidays are over so I've spent a good couple of hours this weekend working on X whilst I've still got time / energy.

Some minor things to start with... the credits have been updated slightly to reflect your input, there's a new section on the title screen called "Notes", which is basically just this blog repeated there. In an ideal world there would be a nice audio commentary but that would take an insane amount of bandwidth, so this is the next best thing ( Maybe a youTube clip with developers commentary at a later date ? )
It's a nice touch and isn't hard to do. It needs some love as I'm not a 100% happy with the presentation ( It's annoying that it's height > 2880 pixels, which means I can't cacheAsBitmap, which in turns means I can't use a gradient mask on it ), but I think it adds to the game overall.

Next up, the explosions are in their final state. Shoved into tilesheets and dropped onto the stage by directly adding the bitmap ( Rather than using a sprite or mc as a container for that bitmap ), which is a sweet tip that Pany posted here. They're animated by using scrollRect ( To just show a small "window" of the tilesheet ) and look pretty damn good. I've got to convert the player's explosion frames to a tilesheet ( It's painfully boring ), but I'm still mulling over exactly how to blow the player up, so that can be put on hold for a little while.

Along with doing the explosion tilesheets FireWorks was fired up and a lot of the existing final images were compressed as 8bit pngs, which dropped the filesize down a bit.

The homing missiles have been optimised too, seeing how no one flagged up any issues with them from the other build it wasn't really needed but it all helps.

Finally, the first baddie type is in. Nice and small "Flockers", which strangely enough are exactly the same as the Flockers in Orbs. Weird that.

They teleport in waves of 5 in a circle, and I'm pleased with them. I need to tweak triggering the player's shield if they teleport in on you, but aside from that they're pretty much done. Oh, the images are place holders before anyone asks.
( Also as I've stressed before over and over, the game play balance isn't done yet. So some levels you'll have cleared all the asteroids and just be sitting there waiting for the baddie waves to appear, other times all the waves will have been destroyed long before you manage to kill the remaining asteroids etc. ).

A good productive weekend for me, as you can see on the X Dev page.

Next up a bit of a tricky one, ideas are more than welcome. I need to allow the player to get power-ups one way or another.
My current thought is to just level up the power-up every level ( The power-ups will all max out at level 5 ), but I'm going to have 3 different types ( Spray, missiles and another one I've not quite sorted out in my head yet ). So how would the player pick which power-up to use ( The mouse wheel would be nice, but then Mac owners are left out in the cold ) ? I'm still in two minds about having a smart bomb, which means the space bar would be used for that.
My original thoughts were to have power-up icons dropped like in Polarity, and the player can shoot them to change the type before collecting them ( Think of the old 19xx shooters ). Perhaps that's the way to go, and just level up the weapon every, or every other, level.

I'm loathe to have a shop in there were you can buy upgrades to your power-ups. It's a lot of extra code and design, and will break the flow. This isn't a game of strategy and missions, it's pure score attack. Even with a shop, it would mean the baddies / asteroids dropping credits for the player to collect, and then there would still be the issue of being able to select the power-up you want to use.

The old style collecting tokens and then selecting a power-up from a list is out ( Nemesis and it's sequels ) because there just isn't the real estate on the screen for a list.

I need to play some old shooters and have a think, but really if you have any ideas please comment me up.

Squize.

Sunday, January 04, 2009 7:19:20 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [5]  |  Trackback
 Friday, January 02, 2009
There's a newly posted update on the XDev page.

This isn't really a "I did all this last night" build, it's what I've squeezed in during the holidays, and is I guess around 8/10 hours work in total, so counts as a 1 day-ish. I'm not trying to be totally anal about how long each build takes.

Now I've actually got to remember what I did. The first main thing I managed to drop in there was the asteroids bouncing off each other. The small ones ignore each other as I think it'll be far too cpu tasking, and too much of a head fuck to be honest ( It'd be like pinball with 30 balls ).
It all seems to work quite nicely, it's pretty subtle, you've got to be watching for it, but I know it's doing it and that's enough for me.

In saying that, I think on later levels ( Level 6 seems to be the first real "kick off" level, around that level it feels pretty sweet ) I may have to drop the checks, or at least test for the number of objects running and skip them when there are too many to test.

Next up I added the "waves". Basically, not all rocks come at you at the same time, there's a trigger point where extra ones will be released. This will need some balancing ( Like all the gameplay, which for me is a long way from being done ) when the baddies are in there.

I guess the biggest thing, in terms of the blog title anyway, is the power-ups. Firstly I added the spray power-up ( I don't think I'm going to stick with that name, it conjures up images of dogs and lamp posts ) which is your standard weapon, plus friends. It looks really good when you've maxed it out at [ Weapon ] level 5.
For all the power-ups there's give and take. For example with the spray power-up, yeah you get 5 shots at once, but the reload time is increased to try and balance that out. It helps me as the coder because it means the games not running as many bullets as it would be if I didn't increase the reload time and will also hopefully bring some balance to the game ( If you max out your power-ups and you're as hard as hell, how do you still make the game fun ? Do you make the baddies that before died with one shot now take 5 shots to keep the challenge going ? If that's the case, you've not actually got a useful power-up, you've just got more sprites on screen. Do you increase the sheer volume of baddies ? Then you could slip into a grind if their easy to kill. It's always a tricky tricky problem ).

The spray PuP didn't take too long, so I moved onto the homing missiles ( Which I knew would ). I've optimised these quite heavily already, but I still think with 4/5 running with a lot of objects there's a performance hit, and that's why I've left them unlocked and maxed out in the current build, so if anyone whose got two mins could give the game a quick play ( 'til around that magic level 6 would be good ) and feedback on their performance and specs that would be great.
If they are generally running crap for everyone ( Fine here, but quad core machine. This baby could run seti@home on it's own, so testing a swf in a realistic enviroment is tricky at times ) then I've still got some ideas to try and claw back some speed whilst still keeping the same look to them.

Squize.

Friday, January 02, 2009 4:03:07 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [6]  |  Trackback
 Monday, December 29, 2008
We're back, hurray!

Hope you all had a good Christmas and got lots of new things to play with ( Left 4 Dead was the best thing Santa gave me, it's the best marriage of "proper game" and multi-player I've ever ever seen. Everyone is going to copy that soon and just ditch the single player mode all together ).

I'm still in a holiday frame of mind, so the posts here may be sporadic as I alternate between working, and eating crap food / watching tv ( I think Olli's the same too ).

There's a new update to X. This is more of a "presentation" build, where I just can't be bothered to try and code anything clever.

The pause mode is in, which is always a nice thing to have done. To try and make it less drab, there's a bit of eye-candy in there, which is a Lorenz Attractor and was ported to as3 from the code at the always excellent Levitated ( I had played with this a couple of weeks ago using setPixel, and just wasn't happy with the results. Rather than let it go to waste I used the bubbles from the depth of field vector effect in 651 and a bit of blur and the add blendmode along with the old faithful infinite bob effect, and it looks ok-ish now. One thought that came to me was the code may be handy for running some types of baddies, could be quite a nice movement pattern and wouldn't require me to think of any more code ).
One thing is that I don't kill the animation during pause, so asteroids keep spinning, explosions keep exploding. This is because the use of movieclips is only a temporary measure, I'm going to wait til we've got final assets before ripping that code out and using tilesheets instead.

The other major chunk of work done is the stats / medals. The medals needs some images drawing for them, and then code to actually trigger them in-game, but all the internal guts is in there. The stats I think are done now, which is cool. Just don't get too attached to them, as every new build will reset them.
I've also added some stats to the level complete section ( I've been brainwashed waiting for things to load on the 360, where they display tips / stats to help you forget you're waiting ) which I'm really happy with.

Following on from a comment from Tonypa, the current level is now displayed, and a level progress bar. I've noticed a lot of casual games show the level progress ( Zuma, Luxor2 etc. ) and it's a simple nice thing to have. It's maybe not that useful now, but perhaps if the asteroids were to come in waves later in the game ( That's a clue btw ) ?

Squize.

Monday, December 29, 2008 6:33:22 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [4]  |  Trackback
 Monday, December 22, 2008
Always a great milestone, when you can play a game, complete a level, die x number of times, read "Game Over" and start it all again.

This to me is when a game is a game, and X(++) has just reached that sexy milestone. Ok, it's not a great game yet, it needs a lot of balancing, and it needs some fun desperately, but it's a game.

Adding the asteroid to player collisions was pretty straight forward, just simple circle to circle checks. I wanted the player to be forced away from the impact, and it works quite nicely. Seeing how the code was written, I used the same bounce code again for when you're shooting an asteroid ( So your bullets actually push the asteroids away slightly ).
It's a little bit weird shooting an asteroid via the screen wrap, as you kind of suck it back towards you, but hopefully shouldn't be too much of a pain to fix.

Next up was making the energy bar decrease. Simple code. Looks nice. Just how code always should be. After that the next logical step was to blow the player up. It's a movieclip, it doesn't get any more straight forward.
That left me with the issue of what to do with the asteroids still on screen, and as I've done in what feels like far too many games, I've added a heat shimmer / wave to the explosion, which blows up all the rocks as it grows.

Another nice simple solution ( I'm not trying to get a rocket into space here ).

From there, it's not much more than

if(--lives<0){
    gameOver();
}

And we've got a game. Sweet.

I don't know how much work I've got in me before Christmas, a couple of days off eating like it's my last day on earth and sitting in front of the tv sounds just perfect right now. Even if I don't do anything tomorrow, we've got a really great guest article to post up, which we're really excited about.
It's nice and apt for this time of year too, I mean Zombies are good all year around aren't they ?

Squize.

Monday, December 22, 2008 8:58:39 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [5]  |  Trackback
 Friday, December 19, 2008
Look at me using a term that'll be a hit with the search engines.

What's been happening in the world of X++ today then ? Very very little.

It's not for the want of trying, it's just been one of those days. Yesterday after posting I ran the game through the profiler as I wasn't happy with the performance, and I wanted to see what was being nasty.

It turned out it was the skybox. Lots and lots of calls to papervision classes, and they were taking the vast majority of the actual game's run time. I've had to remove the planet effect I really loved 'cause of performance, am I going to have to do the same with the skybox ?

Yes.

Annoying as hell, but I can't let the game suffer for the background. If I've made the game good enough you shouldn't even be checking the background anyway, so losing a little bit of love isn't the end of the world. So so annoying though, what the hell can we use 3D in-game for if a couple of spheres make it gag ?

Today was meant to be the asteroids > player collisions, with the plan that you'd lose energy and therefore lose a life, and eventually lead to a game over. Once that's in, the game is a complete game, until then it's just a demo.

First step on this road was designing an energy bar. Firstly I wanted a lcd style display around the lives, where each element would "power-down" as you take a hit. Tried it, and it look toilet. Next was a plan about having some sort of arc around the lives and use a mask to show the energy being reduced. I just couldn't even face starting to design that, as I just knew I didn't have much art in me today. Next up was a simple bar effect, inspired by Wipeout Pulse's speedometer.
Looked crap. All the blend mode effects I tried on the score / lives numbers also looked crap.

Some days you could make Angelina Jolie look bad.

In desperation I ripped the energy bar out of Orbs and tinted it. Looks great. There's nothing especially creative about stealing ideas from yourself, but that's the way it goes some days.

After that, the collisions and all that goodness weren't really going to happen, my spirit has been broken. So instead, it was time to sort out the backgrounds after removing the moving skybox.
Without any movement I figured the way to go was to try and make them look as good as possible, like each one is a bitmap done in an art package, and yet make them random every time ( "Procedurally generated backgrounds" makes a much better heading than "Random backgrounds", and to be fair, I think the backgrounds are slightly more than just random ).

The 3D planet is used from the other day, it's spun on it's axis' so you're always looking at a random part of the planet texture, it's z value is also randomised for scaling, and I move the light source around slightly for the phong shader. Also another smaller planet is created, although it's not always shown.
After that, the skybox is spun around too.

We then grab that skybox and plot it into a bitmap ( ie, draw() ), on top of that is another bitmap with our planet(s) in. Depending on the size of the planet we add a blurFilter, a glowFilter and we tint it.

I really don't know what the odds of having two identical backgrounds are, they must really be vast, and aside from the odd "not as good as I would like" looking levels, for the most part I'm really pleased with how they look.

And... I think that's it til Monday, have a good weekend everyone,

Squize.

Friday, December 19, 2008 7:35:42 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [5]  |  Trackback
The subject title is both the longest, and most perfect, variable I've ever written.

If I could do a whole game using vars like that, it would be like writing a book rather than a game. Bliss.

It seems build 4 was causing more people problems. I'm hoping it's 'cause I was a lazy boy and cut a few corners with the transition, which basically meant it was doing too much at once ( Although on all our test machines, not a single issue. Joy ).
Well that's been tidied up now so hopefully no more problems there.

The score is in, I think that was build 4 and I just forgot to mention it. It uses polling, so every x number of frames the game checks to see if the score actually needs updating.
The reason for this is that I'm using a dynamic text box for the score, which is really costly. Rather than update that more than is needed ( It's not the end of the world waiting a fraction of a second for your score to be updated ) I can just save up a couple of updates and then do them in one hit.
That's the theory, dunno if it makes any difference at all in real life ( ie, I don't know how often the score will increment when playing the game at the moment ).

Also today we've now got levels. Lazy, not tweaked at all levels, but you can complete level 1 and go to level 2 and that's good enough for me today.

One thing I've wanted since the start was a nice sexy rotating 3D planet in the background, that's partly why the skybox is there, so the planet has something to sit against.
Dropped it in today, and wow, it looks so cool. Slightly less cool was the massive hit on the fps. I'd added Gouraud shading because without it, it did look a bit of a pig, but the performance hit was too great.

Shit.

Lots and lots of messing around later, and I had to call it a day on that idea, and look for a compromise. That came in the form of still using papervision to create a 3D planet, but to grab that into a bitmap and then overlay that on the skybox.
It's not as good as true 3D, and it's still not quite there, but it's going in the right direction.

As always, all the builds live here.

Squize.

Thursday, December 18, 2008 11:56:59 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Wednesday, December 17, 2008
Time for a recap on X development stories.

I posted a 3rd build the other day, but didn't bother blogging about it, as, well it didn't seem worth while. The main thing added was the player movement ( Arrows or wasd ) and targeting ( Mouse ) and shooting ( Guess ).
The particles from Orbs were re-cycled to show the bullets expiring ( They have a certain range before they expire. This is 'cause in asteroids the bullets wrap around the screen, so in no time you'd be over run [ With your own bullets ]. Also with a limited range it means you've got to go in perhaps a bit closer than you'd like to shoot up an asteroid ).
The effect is no where near as pretty as when it's running in Orbs, and it took a fair bit of tweaking to get it is where it's at now, but I'm ok sticking with it for the time being. Unlike Orbs, I think in terms of eye-candy the particle effects are going to be well down the list, so I don't want to pour over them for too long. Yet.

The movement is not the usual asteroids control system, of rotate and thrust ( tehehe ) as our good friend Mark at Blastone released a great Geometry Wars meets Asteroids game a while back ( The very sexy Vectoroids ) and when getting feedback on FlashKit games I was the sole voice of "Rotate and thrust" ( Still quite funny, but I'm 36, I've got to stop finding vaguely rude words funny ).
Everyone else acted like I was slightly mental, that those controls wouldn't work in a million years.

I could get on my retro defending soap box, but the retro way isn't always right. There were a lot of shit design choices back in the day, we just didn't know it back then because everything was new, and because we didn't have good design to compare things to. So, instead of me bitching at the kids for not understanding that it's the way it should be played, screw it, let's make it actually handle better than the original. That's not a bad thing to be able to put in place.

( Also it's how Orbs plays, and I like it, and I like to be able to copy and paste ).

One last thing about build 3, our old friend Phil @ flashgamemaker.com has been a star and reported some issues with it, including a freeze during the transition and a pretty piss poor framerate. I'm hoping it's 'cause he's using FP9 on an old machine running the new IE beta, but I'm still going to have to look at it, the transition could be done better so a bit of re-coding there.
If anyone else is having similar issues, please pipe up and let me know. I remember the good old days of Flash, where it was only the Mac version that would play differently ( And no one really cared about Mac users back then ), everyone running Windows would get pretty much an identical experience. Now there seems to be a lot of "On my machine this happens..."

Build 4, this is more like it. The asteroids are in now. An asteroids AI isn't the most taxing thing to code ( A bit of atan2 and you're done basically ) so getting them in and moving didn't take long.
The current images are all greyscale, so a bit of colorTransform action is added to them to try and liven them up a little.

Three big asteroids moving around with a colour tint on them. Next up was to add the player bullet > asteroid collision checks. Again, Orbs was raided, and we've got distance based broadphase collisions in there ( Which is a perfect way to do the collisions in a game like this ).

Getting a trace saying "hit" is only so much fun, so next up was the ExplosionHandler class. Worked first time like a charm ( Tell me how rare that is ).
The large asteroids explode now after 5/6 hits, I should really add the medium asteroids. Tore through that too ( Almost the same code really, I'm not doing anything really clever here ) and finished it all off with adding the small asteroids.

After less than 4 whole ( ie, an 8 hour working day ) days working on this bad boy, we've got a ship you can fly around and asteroids to kill. That's pretty sweet, I'm more than happy with the way it's going.
The original X even to this day is one of my very favourite projects in terms of development, it took 2 weeks and I didn't plan a thing and yet it all fell into place. If I could turn this around in 2 weeks I'd be really pleased.

More whenever really, bye for now.

Squize.

Wednesday, December 17, 2008 9:41:48 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [4]  |  Trackback
 Monday, December 15, 2008
There's a very minor update of X on the X Dev page.

Aside from adding some credits ( I have no sense of priority do I ? Credits done before the game, what the hell is wrong with me ) and finally getting the in-game skybox pretty much how I want it ( Although using a placeholder, which I know I'll come to love and hate having to remove come the time ) quite a bit of time ( Read: Far too much ) was spent on the transition.

Keeping with the TV screen theme, which I think I may have done to death now, I wanted the transition to be a nice distortion / break up effect ( I've been heavily inspired by this After Effects plug-in ).
Part of that, aside from the more obvious static and ghosting / blurring, was splitting up the red / green / blue channels so I could offset them.

With that in mind, copyChannel() got some F1 treatment to see how it works. It's all pretty straight forward, to the point that I'm not going to repeat the syntax here.

What isn't straight forward, is how to overlay the images again to get the original image back. Perhaps it's just me, but I couldn't find one example of how to do that ( Well, I found something using papervision which overlaid planes for a similar sort of effect ).
3 bitmaps, 1 red channel, 1 green and 1 blue. I want to shove those all into a sprite on top of each other to get the same image that I started with. To be honest, I can't think of another reason to use copyChannel() off the top of my head, so I thought I'd be tripping over examples.

But no, one PV3D example like I said, and nothing more.

Cosmic.

The solution ? BlendMode.DIFFERENCE. By applying that to each of the 3 bitmaps it works a treat. Hopefully this will help someone out one day when faced with the same problem.
It amazes me at times how some things are still so tricky to find out about in actionscript.

Squize.

Monday, December 15, 2008 8:08:11 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [6]  |  Trackback
 Friday, December 12, 2008
I'm starting a little experiment today. It could either prove to be something quite cool, or I'll really fall flat on my face with it. Lucky that I don't mind either way really.

Rather than doing a diary style collection of posts about a specific game's development, I'm going to post daily builds. Every day I work on it, even if it's just to tweak a sprites position quickly 'cause it's bugging me, I'll upload that new build.

Now this doesn't mean I'm going to be working on it every day. There aren't going to be a nice collection of sequential posts here until it's done. This is a personal project + Christmas is coming up, and life just isn't so smooth as to allow that.
If I get an urgent job come in then this is on the back burner straight away.

Also if you stick with this ( Never mind me sticking with it ) you're going to see versions which crash, versions which are buggy, versions with no preloader so you're looking at a blank screen for a while. It's a true game in development. I'm not going to fluff it up for you guys, or put some spin on it and work 8 days on it and then pretend that's just 1 day. It's going to be the same as that game you've got in development on your hd, with all the traces that say "Sprite collision failed, wtf?" and all the nasty things that you'd have to hide from the clients build.

That's the caveat out of the way. What are the good parts to this project after all the negative ? I guess that's down to you guys. If you find it interesting then the blog is doing it's job.

X. That's the game. It's an old asteroids clone that I did years ago ( It was my 2nd ever complete game, 2003 some time ? It was part of the "Majestic Trilogy" of games. I'll dig out a link for a future post ).
I've already done a reskin of it, X+, but for some reason that has never seen the light of day. I was looking at it recently and realised it's just a bit too dated now to use, it's as1 so publishing it for F8 so I can use the blendModes in there is really a lot of trouble, so it's either release something that's not as good as it should be, or re-writing it in as3. X++ it is then.

I'm weird when it comes to coding. I know a lot of developers just like to get in there and get the engine working, and then work back from that. I'm very linear, like a bad fps. I need to start from the beginning, the title screen. It's important to get that look & feel in place to set the tone for the rest of the game.
So that's what we've got, a title screen. There are buttons that rollOver, but don't lead anywhere. The background image is a place holder as we're going to have a flv running there instead ( I did have a flv to test in place, borrowed from here ( Click the video button ) but it bumped the file to 9meg, so it's been reduced to a static image until we get the final render done ).

Enough words, here's the front-page for the xtreme coding experiment

More soon, although I'm going to try avoid saying what's coming, 'cause it usually falls through and I go off and do something else.

Squize.

Friday, December 12, 2008 11:45:16 AM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [7]  |  Trackback
 Thursday, December 04, 2008
Our first project with Brandissimo is finally live, and sitting on the NFLRush site.

Just to caveat the excitement a little, the NFL site requires a sign up, and I'm sure it may be a subscription service ( Read: You've got to pay ) [ EDIT: Nope, its free, just needs a sign up. Sorry about that, and thanks to Andy for pointing that out ]

To compensate for this, I'm just going to post some screen shots, a couple from the intro movie, and one in-game one. Then in conjunction with the development posts ( For some joyous reason I can't look back at old posts and be logged in at the same time, which means I can't just simply give all the dev. posts a GMM category and then just refer you to the tag cloud. Cosmic. So instead, the development ran from the start of Sept '08, to the 1st Oct. Cutting edge blog technology in all it's glory ) you can use your imagination to play the game.
That's got to be better than actually playing it hasn't it ? I mean you can imagine any old mental things. For example, I'm imagining that I had the time to scroll the screen rather than just making it flick...

gmm_grab1.jpg

gmm_grab2.jpg

And a little something in-game...

gmm_inGameGrab.jpg


A really enjoyable project, some great assets to work with ( I'd never have opted for that art style in a million years ), some great people to work with at Brandissimo and quite a nice little game at the end of it. All good.

Squize.

Thursday, December 04, 2008 11:59:41 AM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [10]  |  Trackback
 Monday, October 13, 2008
Every now and again there's a 48hr game comp on FlashKit games. I've not entered since the 2nd one ( Which I was really pleased to have won, so I wanted to keep my 100% record ) so I felt it was time again, to see if I can still turn it on.

It works by everyone offering up a couple of words and then at kick off two are chosen at random and that's the games theme. This time it was "human brain" and "micro-organisms".

The theme was announced at 1am ( Saturday ) and the obvious thing for me was a shoot'em up over the brain, zapping the invading baddies, so I went to bed. It's what us coders do best.
Saturday afternoon I was mulling it over, an arena shooter would be cool but I'm meant to be finishing Orbs off as it is without trying to do another, plus I knew realistically that I'd have about 16 hours to do this. Ok, a Galaga style shooter. But that means lots of attack waves, plus a scrolling background ( Without the scrolling background it would feel really really old school ). Scratch that then.

I've never written a mouse avoider as I've always found them trite and throwaway. Perfect!

Saturday I didn't get much done, the England match got in the way, mainly the front-end and the overall structure was nailed. The power-crystals ( Or "geoms" as they're actually called in the code 'cause I just couldn't think of a better term ) were in and running which was good 'cause I knew a lot of those routines would be used by the baddies.

Sunday, erm, well I finished it off. I managed to be the first person to post up a final game, as I was sick to death of working to be honest ( It only took around 12 hours in total, but by the end I was glad to see the back of it ).
The sounds were the last thing to be added, I found an old tune from a game I'm not going to finish so re-cycled that and the sfx are also from various old games. I'm not a 100% happy with them, and I wanted to add another baddie type that would explode when killed which would have caused a cool chain reaction with combo's etc. but I felt it was better to have a complete ok-ish game done on time rather than try for more but post a game with a lot of loose ends in there.
For me the comp is as much about finishing by the deadline as the game itself.

If you'd like to see the fruits of my labours, click me

Also I've posted the source, in two flavours:
Just the code ( 16k )
Code with fla's ( 2.5 meg )

It was written in Flex and I very much doubt it'll run out of the box straight away, but it includes the preloader code which may be handy.

Also all the comp entries are here. I can really recommend giving them all a play as there's some great work there in such a short space of time.

Squize.

Monday, October 13, 2008 12:33:38 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [2]  |  Trackback
 Wednesday, October 01, 2008
I'm currently touching wood ( tehehe ) that GMM is gold.

Guess how long it's taken ?

This is going to be a two pronged post, I'm going to both wow you with visuals and bore you with stats. Stats first I guess, here's the breakdown of how long the game took blow by blow

Attract Mode: 1hr 9mins
Bots: 13hr 33mins ( I had such a mare with these )
Class Structure: 10mins
Corn Power-Up: 5hr 20mins ( This was re-used for the other power-ups, hence it taking so long )
Display Map: 32mins
Dummy Trap: 2hr 34mins
Game Complete: 58mins
Game Over: 24mins
Golden Ball Power-Up: 49mins
Health Power-Up: 1hr 37mins
Hidden Baddie: 2hr 47mins
HUD: 1hr 38mins
Instructions: 2hr 33mins
Level Complete: 40mins
Level Design: 7hr 38mins
Level Plotter: 7hr 39mins ( What are the odds ? )
Level Structure: 1hr 22min
MiniMap Layout: 1hr 31mins
Mud Power-Up: 1hr 8mins
Pause Mode: 30mins
Player: 7hr 37mins
Points anim: 24mins
Preloader: 34mins
Score: 7mins
Sounds: 3hr 22mins
Tiles: 2h 54mins
Transition: 25mins
TrapDoors: 3hr
WaterTraps: 1hr 23mins

Now this may seem incredibly anal, perhaps to some degree it is, but when working for yourself it's important to keep track of where your time is going. It helps budget for the next game, as you'll see a pattern ( So for example a preloader won't take long, but you know the player and baddie routines will ). A lot of common sense I know, but seeing how long things actually take can be a useful eye opener.

Want to see the map for level 1 ? Go on then seeing how I promised

gmmMap.png

So from here the clients need to give it the once over, make sure I've fixed what I was meant to, tweaked where things should have been tweaked and sign this bad boy off.

K, time to work on the arkanoid game again...

Squize.

Wednesday, October 01, 2008 2:30:47 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [6]  |  Trackback
 Thursday, September 25, 2008
I worked 'til gone 3am last night, and I'm beyond tired, so rather than a blog entry covering how I knocked a lot of things off the to do list for GMM and designed level 2, here's a link to a viral clip that Chris at errorWare sent me today that made me laugh.

This, in it's own bizarre way is totally safe for work.

A less tired and lazy post tomorrow, if for no other reason than I've got to use the last lyric as a title.

Squize.

Wednesday, September 24, 2008 11:16:35 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Wednesday, September 24, 2008
Well my days being split in two carries on.

During the day I'm working on the Arkanoid game for gimme5, evenings it's back to GMM. I can only say thank God both of these are coming to a close at roughly the same time 'cause it's so nasty working on two projects at once ( I equate it to writing two different novels at once ), not just in terms of swapping and changing ( as2 to as3 to as2 ) but the sheer number of hours a day I'm working on them.

Most of yesterday was spent on the g5 game. Myself and Ronnie the tech. lead at g5 spent hours nailing down the server side intergration for the level saving / swapping. That's nearly done, and I'm really hoping with one final push tomorrow it'll be done for good.

Between that I was adding all the speech to the game, and it works really well in place. Today was more of the same and clearing off some of the really obscure bugs. The To Do list for that is finally going down.

Last night on GMM was spent adding sounds too. Thankfully the client sent me a zip with pretty much all of them in there, and they're all pretty spot on, which is great.
It was also nice using my as2 SoundHandler class again, the one in as3 is very make shift at best, the as2 has been built up over the years and is so easy to use and does everything I want ( For example, sound.setPanDistance() calculates the mc's position in relation to the center of the screen and sets the pan accordingly ).

Pretty much a whole day doing sounds for both games then. This morning ( Before starting back on Arkanoid ) I managed to finish off the instructions for GMM. Not hard work, but lots of fiddly aligning and just boring really.

I think tonight I'm going to try and knock up a couple more levels for GMM. Only level 1 is done so far, so getting a couple more done will be good, and it's a break from actual coding. I'll be able to test it a lot whilst making sure the level plays well so the to do list will grow ( It's always the way, when a project is coming to the end you find you'll delete one thing off your list but find at least another 2 to add to it ).

I'm just going to be a bit self indulgent, not for the first time I know. I hope I'm not the only person who's wanky enough to google themselves. Well I googled "Gaming your way" and was wrapped to see we've "made" it on google.

gywGoogle.png

Check us out all indexed. Ok it's only the blog, the site itself seems to be as popular as the plague, but it's just a place for us to whore ourselves in a grown up way ( "In terms of traffic it has more than met their expectations" all nice and nu-media friendly )

After that, I thought sod it, let's see what "Squize" brings up. I came second, the top entry being

"I masturbate weirdly. I squize my hips with my hand in the middle. Even with my panties on... Weird?
Anyone else does that? I'm 13..."

I ( For once ) just couldn't make it up. That's my sails deflated, 2nd to a 13 year not knowing how to frig.

I guess there will be more of the same crap, just worded differently, tomorrow.

Squize.

Wednesday, September 24, 2008 5:18:35 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [3]  |  Trackback
 Monday, September 22, 2008
Back to Flash after Fridays rant.

Today was a bit of this and a bit of that.

I'm having to finish of an arkanoid clone for gimme5, a hang over from when I worked there. Improved the collisions ( Again ) and finally finished the baddies off.
Still a lot of things to do, it's becoming a long drawn out project that I can't wait to see the back of to be honest.

Back to the lot more fun GMM. I started the player shooting routines Friday and they're nearly finished after starting it up again today. Doing a game in ISO just adds that layer of complication to it, but I've got projectiles flying around quite nicely now, and in the past 30mins got it so the baddie bots know they've been hit and power-down for a couple of seconds allowing you to run past.

Right now my to do list stands at:

* Instructions
* Golden Ball - shoot / test for hitting bot
* Mud - shoot / test for hitting bot
* Bots
* Sounds
* Score
* Design levels
* Test right hand exit
* Remove traps from fore/background mcs

The Bots are nearly done, I'm just removing the final kinks with animation frames going a bit mental and stopping them just sitting on your head when they've hit you until they drain all your energy.
The two remaining power-ups ( Golden Ball / Mud ) shouldn't be too much work now the first power-up is in there and working ( It's really just the end result when a bot is hit by one which differs ).
Everything else is just bits and bobs, with the sound looking like it'll take the most time out of all that.

So it's slipped, but it's still on-track (  ie there's nothing left that fills me with fear ). In terms of actual time spent on it, 50 hours 48mins, which shows that I must spend an awful lot of the day just day dreaming instead of coding. It's something I really need to tighten up, if I was doing proper 7 hour days then we'd be looking at just starting day 6 now ( In my defence a decent chunk of the day seems to be taken up with admin stuff ).

Anyway until tomorrow that's it from me.

Squize.

PS. Just as a sidenote, we've got a great guest article coming up this week, which we're really proud to be presenting here.

Monday, September 22, 2008 9:22:49 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Wednesday, September 17, 2008
So today is the last day I should be working on GMM. I've got a bit of a confession to make ( Well two actually ).

The first one is that today isn't actually the real deadline. I don't know when that is, I think 4 weeks or so away. That's when the client starts emailing a lot more and things start getting slightly strained. That's when clients are still firing off "It's perfect. Can we just alter...". That's when you're sick to death of it. The deadline is when you realise you've really under quoted on this job as you're still killing yourself trying to get it done on time. It's when you regret having those couple of lazy days and when you realise that the next job isn't already in the bag yet, so you've got both a game you're pretty jaded with to finish off, you've also got to whore yourself around to make sure the following months bills are paid.

Then why have I been counting today as the deadline ? Because you need to work to the budget and not the timeline ( Where possible ). You have your day rate and you divide the budget by that, that's how many days work it is.
When I started off trying to get into the industry and was just writing games to learn my art, I always did that even then ( Although my day rate was a lot less in those days. A couple of years experience and some shiny awards bumped that up ). It stops feature creep and ensures the game is done, not 95% done but good enough to release.

Now with GMM there was very little budget. No where near enough to do what was needed. Sometimes projects are like that, and sometimes you have to take a short term hit for a longer term gain. After seeing the assets and chatting to the client I knew I wanted to do this, so the hit in my pocket wasn't an issue ( Or rather not enough of an issue ).
So I did the above budget/dayRate=days formula, and then multiplied it by 2. I thought it would be possible to still make the game everything it should be in that timescale ( 10 working days ). In effect after day 5 I was making a "loss", and every day spent on it after today ( It's day 10 already ) I would be making a loss on my cheaper rate.

It's hardly the end of the world. I still think Flash developer wages are stupidly inflated compared to real life. A loss when earning good amounts is still better than a lot of people having to dig holes in the street or change patients bedding. It's all relative.
I speak to quite a few London based freelancers who charge a lot more per day than I do. That's great if you're working on some big ass media campaign where there is a silly budget involved. Rip the arse out of it, but personally I'd rather do the odd job that doesn't make as much rather than this rigid "£xxx" per day.
GMM is going to be a good little game, and if I'd stuck rigidly to my day rate then either I wouldn't have got the job or I would have had 5 days to do it, which would have resulted in a crap game ( 3 days to make it, a day to test and debug and a day for client amends. Hardly the most time in the world to make something shine ).

I think that's one of the key reasons why there are so many piss poor adver-games out there ( Don't believe me ? Check out thefwa. Filter it to show games, and have a play. They will look great, but tell me how many you'd play more than once. Or even how many you enjoyed playing. Or even how many you admire as examples of good gameplay ).
It's mainly due to the lack of good coders, never mind good game coders. This shortage means that either designers "Who can code a little" are making very pretty but very empty games, or agencies are getting freelance coders on board who know they can charge £xxx a day and sometimes it means there's not enough budget to make a good game, just enough to cover their costs and have something come out the other end ( There are of course other factors, clients with no concept of games, designers with no concept of games etc. ).

I don't think there's anyone to blame, and I don't mean it as a blankit critisim of freelancers ( Far far from it ) I'm just trying to put into lots of words that sometimes the art should come first.

Right I mentioned at the start that I had two confessions. The second is that the game isn't done yet. In fact the to do list has hardly been dented.

The "hidden baddies" proved to be a real bitch to get working, and as soon as I post this up ( And after a smoke, obviously ) I'm back onto the baddie bots ( Pac Man ghosts ) which I spent just under 4 hours on yesterday and need at least a couple more hours today to finish off.

Squize.

Wednesday, September 17, 2008 11:14:00 AM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [5]  |  Trackback
 Sunday, September 14, 2008
It's all got a bit blurry what's been done when. That's what happens when your diary slips, it just merges into whole big lump of vague memory.

I finished off the last entry about adding a play again button to the game complete screen. That's done, so the whole ability to play the game from start to finish and start again is in. Feeling like a proper game now.

I spent a long time adding the trap doors to the game. The traps themselves were straight forward enough, I just had a real problem getting rid of them once they were triggered. It all worked fine, you'd fall down a hole, recover, leave the screen but when you came back the trap would be there again. Glaring at you. It was just a silly mistake on my behalf, but took ages to find.

After that the water traps were pretty straight forward, they just used a lot of the same code. The only slight snag with these was the falling down splat on your face animation. It's a big bigger than normal ones and in one direction there would be a depth sorting issue with the players arm sticking out too far. A quick kludge check, and it's all good.

I also added in the preloader and a pause mode, and it's always nice to test the "Quit to menu" option and it works first time. No nasty code running in the background that I'd forgotten to kill.

After showing it to the client there was a bit of an issue about the control scheme, so a quickly knocked up controls page ( Only if you've skipped the instructions, and lets face it you will. I know I would ) was dropped in there at the start of the game.

Just out of interest ( And the fact that it looks like I've done very little for 3 days so I need to pad this post out a little with some boring filler ), below is the output from our sweet notifier app which tracks all that we do

Attract Mode: 13mins
Class Structure: 10mins
Dummy Trap: 1:22
Game Complete: 58mins
HUD: 1:10
Instructions: 51mins
Level Complete: 40mins
Level Design: 1:09
Level Plotter: 7:06
Level Structure: 45mins
Pause Mode: 30mins
Player: 5:32
Preloader: 34mins
Tiles: 1:55
Transition: 25mins
TrapDoors: 3:00
WaterTraps: 1:21

All that added up should come to 49 ( 7*7 ) hours, and if it doesn't it shows that I've been a bit lazy :)
( I know it won't even be close as the last couple of days I've been sorting out the tax man and dealing with the joys of tooth ache, so the work has had to take a bit of a back seat to those ).

This coming Wednesday is my deadline. I think it's going to be a bit tight, there's some big routines to do before then, and my to do list reads as follows:

* Instructions
* Power-ups
* Bots
* Dummys
* Hidden bad guys throwing dummys
* Sounds
* Player health
* Game Over ( After losing all health )
* Owls

( I know with no real concept of what the game is that's as vague as hell, sorry, my hands are tied as always. Power-ups are collectables which you can shoot at the Bots, who are going to be pacman ghosts. Dummy's are obstacles that are triggered by hidden traps which block your path, and that the Bots can push around. Everything else I think is clear enough, oh apart from the owls :) ).
So 3 days to do all that, fix any bugs ( I've noticed a couple with the fore-ground plotter ) and shoe horn in any ammends from the client.

This is why I can't give up smoking yet.

Squize.

Sunday, September 14, 2008 3:07:31 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Tuesday, September 09, 2008
4
A quick little ol' recap of what was done yesterday ( On GMM ).

I designed the first level ( Using the always easy Mappy ) which took quite a while, and I think it's going to need some tweaking. It gets tricky if you leave / enter a screen on the tiles near the rear corner as you really can't see where the hell you are ( Esp. if there's a big tree slap bang in the middle of the screen ).
I'm hoping it's just a case of tweaking it slightly rather than re-doing it as today I'm at the half way point and there's very little time to dive in and re-do a whole level. Speaking of which, I'm going to hold off designing the next 4 levels until all the baddies / traps are in and working as it'll make a big difference.

Having a working level in place also highlighted a bug, where I'd miss-counted the number of tiles before changing screen, so you could walk out of one screen and straight into a wall on another. Not good.

Added some more tiles to the tileset. I think there's a couple more but they're only minor wall variations now.

Biggest job of the day was putting the level exit in there. I had a wealth of sorting issues with it ( It's huge ) and for a while I got that sinking "The depth sorting is screwed" feeling. I had visions of having to chop up this large vector object, which would have taken ages. Luckily I took the easy option and just changed the tiles alignment and that fixed it a treat ( All the "Bigger than one" tiles are aligned so the bottom right ( SE ) tile is aligned to the other normal tiles. With the exit I just altered it to being the back left tile aligned there. It would break if walking down the side of it, but some well placed wall tiles on the map stop that ever happening. Iso is so hard to explain in words, so thanks for fighting your way this far ).
So the exit is displayed, next up was getting it working. The exit is two tiles wide, so I just have to check the players x/y to the two exit x/y positions. Easy. Oh shit, the player needs masking as he walks through the exit door ( Remember the depth sorting is a big fat cheat, he can't really pass beneath tiles correctly ).
Creating a mask and positioning it correctly didn't actually take that long, it was just one of those [ Many during development ] moments of "ffs, I really don't need this".

With the player being able to complete a level now, next up was to do the level complete screen. I didn't actually get any assets for this so I just knocked up something nice and simple using the format for the game complete screen.
With the level complete screen done ( See how it all rolls into one ) it made sense to do the level bumping code, and with that the loading next level stuff.
Right from day 1 the game's been able to load and parse maps, so this was just a case of a couple of extra call backs ( No events in this game ) and figuring a way of showing that the next level was being loaded whilst you bask in the glory of the level complete screen.
Rather than add a spinner or loading bar, the level data is quite small, just over 10k atm, so I just hide the "Play next level" button until it's loaded. Lazy I know, but the majority of people have a nice fat connection these days so the wait will be a couple of seconds at most ( Plus the levels will be buffered internally once loaded, so the pause will only be there the first time you play it ).

Keeping this theme of rolling from one aspect to another, next up was the game complete screen. I just shoved some times and a bit of score in there and it's all but done.
I called it a night before finishing the "Play again?" button, so that's where I'm starting today. Right now infact. So until tomorrow, bye kids.

Squize.

Tuesday, September 09, 2008 11:52:54 AM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Friday, September 05, 2008
I didn't touch GMM yesterday, so to keep up the constant supply of development highs and lows I thought I'd write up today's instalment whilst it's still fresh.

Today's objective was to be able to move from one screen to another, and joy of joys, you can. It was quite straight forward, took a little while to keep track of all the sets of coords I've got to use ( The local map position, ie the tile at 0,0 on the screen, the local player position within the current screen and the player's position within the whole map ) but nothing too painful. Messed up the re-positioning of the sprite a few times ( You leave the screen at the far right you should be repositioned on the left of the next screen ) but that was where the coords above were just not clicking into place in my head.

Once that was working it needed a quick and simple transition from moving from one screen to another. A quick use of draw(), and a tweened mask and it was all done and works nicely ( Same way as the transitions are done in both Fuel-Factory and Toxic Shock. Grab a bitmap of the current screen, attach a mask to it, run the effect ).

Finally I tried adding the big ass tree tiles. These bad boys took a while, but only 'cause I'd got the keyframe order out of sync ( The tiles are old school, laid out on keyframes like the good old pre-bitmapData days ).
Once that was working they went in there a treat and with no depth sorting issues with the player ( I'll have to be careful where I position the "wall" tiles around them though, as they are huge and it could cause problems, but nothing a little bit of forward thinking won't fix, and a million times easier than splitting the tile up into 32px wide strips ).

And I think that's it. Doesn't sound like much, but it's coming along nicely. Weekend off so Monday will be spent adding the exit to the maze and testing for it, so it should almost be a game then. If by day 5 all the level progression, game over, game complete stuff is done I'll be really happy and bang on target.

Also early next week Olli should be posting about a new complete project that he's been working on for a super sexy huge name client who we're obviously really pleased to be working with.

Squize.

Friday, September 05, 2008 8:49:07 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, September 04, 2008
I did write a great entry, quite possibly the greatest prose ever written, but I / the blog messed up and it was lost.

Instead you'll have to make do with the usual shit quality of writing.

Where did day 2 take me with GMM ( That's it's code name from now on ) ?

I added in all the "surround" tiles. In a usual iso game the playfield is a diamond shape. To fill this up a little and to keep it more inline with the look & feel images I've filled this area in with tiles that will be on other screens ( If that makes sense ). Hint of blur and darkened up a little and it looks pretty damn sweet.

Next up was the player. He's in. He walks. He stops at walls. All good.

After that, the dreaded nasty depth sorting. It's not something I'm usually very good add, I always struggle to get it spot on, so I had a bit of research around how other people do it. I found the way I normally do it, ie depth=mc.x+mc.y*playField.width, and a really nice looking way which calculated the z-depth correctly.
My solution was to do something totally different.
All the tiles have a big healthy gap in their depths so I can drop sprites in-between them without there being any sort of clash of depths ( as2, no depth management here ). The player sprite finds out which tile his on, gets it's depth, and make sure his depth is higher. As simple as that.
When moving the player sprite looks at the next tile and grabs it's depth, so it's always at the correct depth ( I wish I could find a way to explain this without using the word depth so often ). There was a slight issue when moving in directions which would mean the next tile would have a lower depth than the one he's standing on ( ie, moving up, or NE ), that was fixed by only updating his depth halfway through the walk cycle.

It all seems nice and solid so far, and quite simple to do. I'm just hoping it doesn't trip over when there are bigger / taller tiles in there.

Then there was a slight bug with the actual movement. He'd drift off course ever so slightly every move, which meant that after no time at all he'd be quite a way off the tile he was meant to be on. Olli came up with the fix, which is another simple one, the player just finds out which tile he's on when he's finished his walk cycle and then aligns himself to that. Piece of piss.

I think that's it. I'm sure I wrote a lot more first time, but it's never as fun second time around. Today has been spent working on an old project which is like an albatross hanging around my neck, so no new update tomorrow ( I know I've only lasted 2 days, but to be fair I'm not missing a day out as such ). Maybe I'll post some trite eye-candy here to fill the gap.

Squize.

Thursday, September 04, 2008 4:49:38 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Wednesday, September 03, 2008
I started a new project yesterday so I thought it would be a good time to see how long I can maintain a diary of it's development. It's only got 2 weeks ( 10 working days ) allocated to it, so surely I can write something new and interesting every day for 10 days... well interesting is pushing it a little bit.

Starting a project is always a double edged sword. Cool, it's a new project with all the possibilities that go with it. Shit, it's a new project so I've got to set up all my usual classes for the millionth time.

To touch on things without giving anything away, it's an iso maze game. Before kicking off it was agreed it wouldn't scroll as the dev time is so tight, so it's just going to be a flick screen game like the old greats such as Head over Heels and Knightlore.

Day 1 is setting up classes. This game is going to be done in as2 ( Due to the tight deadline, did I mention that ? ) as although I've fallen for as3 at last, it's still a ball ache for a lot of things.
I've already received all the assets ( All of them. Up front. Amazing ) and there's lots of nested animated movieclips, which as2 does well, and as3 doesn't, so that helped swing me towards as2 for this one.

Hello fdt and mtasc, I've missed you bad boys. Still quicker and better than Flex. Things that are tripping me up though are Void ( It took forever to get used to void, and now going back it's taking just as long ) and _alpha, _x, _y etc. Any property with an _ basically.
It's amazing how quickly I've lost the habit of using those.

Code wise we've got the core classes in place ( Player, GameController, Master ( enterFrame mainloop ) ) and I've ripped the map loading routines from Toxic Shock ( External map files are a million billion times easier to work with ) so the game can load in it's data.
The biggest routine of the day after the LevelHandler is the LevelPlotter. I've only ever done 1 iso game before, Fuel Factory, and I'd forgotton what a pain it is to align the tiles correctly.

By the time I called it a day, we have a title screen ( No instructions button yet, and a missing anim, but almost done ), a swf that loads in it's own data and parses it, the game HUD with working timer and a 10x10 grid of iso tiles plotted. Good start to it, and I'm aiming to hit it hard again today.

Squize.

Wednesday, September 03, 2008 10:10:45 AM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [2]  |  Trackback
 Monday, August 04, 2008
Alpha is out, now there are just a few things left to do to improve the useability of the editor and wait for the final informations on how the main game should handle custom levels.

Oh and there are just a few levels to enter ... 130 to be honest.

On Friday I had the "more-than-bloody-stupid" idea to enter a few of them. I did 2.

The one that killed 100% of my motivation was a nightmare of force fields all pointing in different directions:
cc_lvl_22.jpg

Believe me when I say looking at this level in full size can make you want to puke.

After some agonizing hours, I finally started to write a file converter that should be able to read in the binary file format of the original game. OH JOY!

This somehow kills the edia of entering the levels and testing them along the way to see if the engine can handle all the weirdness of the original creators (and I still do believe that some of the levels where purely designed to piss the player off as much as possible).

oh well ...

nGFX

Monday, August 04, 2008 7:28:07 AM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Friday, August 01, 2008
Well here it is, the "Too early to show mix" of Orbs.

No preloader, so stick with it ( About 700k )

I figure this post is more a show and tell as opposed to anything more. There are lots of bugs so I'm not really after reports ( Thanks ), this is very WIP, and I've only really posted it here due to reasons outlined in the post from the other day.

The gameplay will be more refined in the final version, "Campaign" mode will be the primary game type ahead of arcade ( There's not even an option for it yet ), and there are quite a few more baddie types and a lot of love to go into it yet.

A quick spurt of instructions:
Your objective is to protect the Orb. As long as it's got power it can re-generate your ship. WASD or Arrow keys move you around, aim and shoot with the mouse, P to pause.
Some of the options work ( Stats for example, although there are some unfinished ones in there, and a lot more to go in, along with a lot more medals ), but most don't.

It's mainly a case of looking around and watching the particles right now, but they are quite pretty so far.

As I do more work on it I'll flesh the posts out about the tech. side of it as I've gone to quite a bit of effort to get this bad boy running as fast as possible ( Which is sheer bliss. In real life you never have the time to even write the word optimise never mind doing it ) and hopefully development will go onlong in fits and starts like it has since the project started 'til one day it can go free into the world able to stand on it's own two feet.

Enjoy.

Squize.

Friday, August 01, 2008 8:19:41 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [8]  |  Trackback
 Thursday, July 31, 2008
Great day, Geometry Wars2 is out today ( And I've nearly nailed the collision routines in the arkanoid "style" game I'm doing at g5games, but I digress ). Regular readers will know I've been working on Orbs forever now, which is inspired by the GWars look and feel, so I've been keen to check the sequel out ( For the whole week or so since I heard it was coming )

800 points later, and wow. It's sex.

When you shoot a baddie, it drops a geom ( Correct me in the comments if I've given that the wrong name ). When you get close to them, they get sucked towards your ship.

Hmmm, just like the credits I coded the other day in Orbs.

Also there are new things, called "gates" ( Corrections always welcome :) ), where you can shoot them and your bullets rebound to kill baddies. It even keeps track of how many rebound kills you've got.

Hmmm, just like when you shoot the orb and it rebounds and kills a baddie.

Arse. For fear of Orbs coming out and everyone just pointing the finger of copy catness, it's forced my hand ( Yeah the title makes sense now, these posts aren't just thrown together you know ) to release a demo sooner than I'd rather.
Hopefully by Saturday we can have some particle porn up here. I'm just thankful that Bizarre haven't got Pong in the pause mode.

Squize.

Wednesday, July 30, 2008 10:21:16 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [2]  |  Trackback
 Thursday, July 10, 2008
I've been pulling my hair out for about an hour with this beauty, and after finding the solution I thought I should share here, if for no other reason that I know I'll get it again and lose another hour ( I'm 36, my memory is shot ).

When trying to make a new bitmap instance of a bitmap in the library, along the lines of:

        [Embed("/_assets/assets.swf",symbol="bouncerBitmap")]
        private var bouncerBitmap:Class;

        var bm:Bitmap=new bouncerBitmap();

I was getting invalid data when running the swf, basically it was failing big time.

Had a bit of a google and found this. For some beautiful unknown reason, sometimes when you import a png to the library and set the compression to jpg ( Although in this case I actually hadn't, Flash just took it upon itself to make it a jpg for me ) it screws up.

Joy.

Anyway all fixed now, and I've even got this as a reminder for next time.

Squize.

Wednesday, July 09, 2008 10:48:45 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Saturday, July 05, 2008
As regular readers will know, we've been done over with a hacked version of "Law of the West". Instead of just bitching about it, we've decided to be pro-active.

This is going to take a number of forms, one of which is SICO, or "Source In, Crap Out".
We looked at what encryption and obfuscator software there is out at there, and came across irrFuscator. It looks pretty cool, and at 69 euros isn't going to to break the bank, but it also looked like it was something we could do ourselves without too much effort.
Where SICO fails compared to irrFuscator is that from what I can tell it takes the whole project and messes it up, so public functions ( And therefore getters / setters ) get screwed with too, whereas our project just takes one file and so has to leave anything which could be called from a different class alone.
Also it converts strings, but it looks costly. Looking at the example on their page, "end" gets converted to irrcrpt(23, "uzd."). That kinda looks like a static class is added to the project with a method called irrcrpt, which takes the first value as the "key", and I guess it's just a simple XOR with the string value.
Fine for scrambling a filename, but I think it would be too harsh [ In performance terms ] to do that to every string in the game, so it's easy enough to just add a method in like that by hand for your filenames / passwords / cheat codes etc.

( In case this reads like I'm just bashing irrFuscator, I'm really not. It's better than SICO, I'm just pointing out the differences ).

So what can our baby do ? Here's the loader class we use for it:

package Classes {  
    import flash.events.Event;
    import flash.net.URLLoader;
    import flash.net.URLLoaderDataFormat;
    import flash.net.URLRequest;
    
    public class IO {

//---------------------------------------------------------------------------------------
// Properties
//---------------------------------------------------------------------------------------
        private var loader:URLLoader;
        private var callBack:Function;
        
//---------------------------------------------------------------------------------------
//Constructor
//---------------------------------------------------------------------------------------
        public function IO(){
/*
Null constructor, we don't need to do anything here
*/

        }

//---------------------------------------------------------------------------------------
// Public
//---------------------------------------------------------------------------------------
        public function toString():String {
            return "IO";
        }        

//---------------------------------------------------------------------------------------
        public function loadScript(filename:String,callBackArg:Function):void{
            callBack=callBackArg;
            
            loader = new URLLoader();
            loader.dataFormat=URLLoaderDataFormat.TEXT;
            loader.addEventListener(Event.COMPLETE, xmlLoaded);

            var request:URLRequest = new URLRequest(filename);
            loader.load(request);
        }

//---------------------------------------------------------------------------------------
// Private
//---------------------------------------------------------------------------------------
        private function xmlLoaded(eventArg:Event):void{
            var source:String=eventArg.target.data;
            callBack(source);
        }

//---------------------------------------------------------------------------------------
    }
}

And here's what it looks like after being run through SICO:

package Classes {  
    import flash.events.Event;
    import flash.net.URLLoader;
    import flash.net.URLLoaderDataFormat;
    import flash.net.URLRequest;
    
    public class IO {

        private var _V64K0q:URLLoader;
        private var _87qjufb1lsM:Function;
        
        public function IO(){
        }

        public function toString():String {
            return "IO";
        }        

        public function loadScript(M85u8En4i:String,_87qjufb1lsMArg:Function):void{
            _87qjufb1lsM=_87qjufb1lsMArg;
            
            _V64K0q = new URLLoader();
            _V64K0q.dataFormat=URLLoaderDataFormat.TEXT;
            _V64K0q.addEventListener(Event.COMPLETE, _v1zr6rD62q);

            var kDu541CN2C5:URLRequest = new URLRequest(M85u8En4i);
            _V64K0q.load(kDu541CN2C5);
        }

        private function _v1zr6rD62q(_wVl6q:Event):void{
            var n1XScOB03y:String=_wVl6q.target.data;
            _87qjufb1lsM(n1XScOB03y);
        }
    }
}

Pretty mashed up. There are still some quirks to it which need ironing out, and it's not got a list of reserved words or anything that cool, but that code is nasty once run through it.

Next we need to actually make some sort of front-end for it, ideally using Air to get to play with that, more possibly with Zinc to make it easier, and then decide what to do with it. It won't ever be for sale, it may be a case of we just give it to friends and let it spread gradually like that, we're not sure yet, but it will be given away. There's no point bitching about hacking, and then coming up with something that makes our stuff safe and screw everyone else.

And that's part 1 ( Or 0.5 ) of our push to try and get the community as a whole being a bit more protected, there is more to come. Olli and I have had some long chats the past couple of days. We both came to the conclusion that yeah, having hacked games floating around sucks, but there are some things which are more acceptable than others.
If LoW had been hacked to use the hi-score component of the system it's been hacked for ( Some "shovelware portal in a box" system ) and everything else had been left intact, then we can swallow that. Just. The game gets spread so the sponsors happy, we get our credit out so it's not too bad for us, the ad gets seen etc. It's not that bad. It's only when the game is just ripped of everything like that we get pissy.

Part of this process of stopping it is to actually get involved with the boards that link these games, for fear of sounding like a politician, it's about education. A lot of sites with hacked games on are run by decent people, just trying to make a couple of quid, and not really knowing about any harm they could be causing 'cause they never ever have any contact with a developer.
Flash games are percieved as such a throw away commidity that the line between IP theft and hosting becomes very blurred. A lot of people who run boards wouldn't dream of hosting mp3's, but see Flash in a totally different light.

We really fucking resent having to spend time on things like this, but if we're in the position of toying with ads and sponsorship as well as the client based work, then we need to protect our IP. Like we all do.

There's more coming,

Squize.

Saturday, July 05, 2008 4:49:49 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [4]  |  Trackback
 Wednesday, July 02, 2008
Sorry folks yet again no image ... but some code :)

The current game (let's call it CC for the sake of it) is getting close to the point where I would declare the main game engine done, most of the events are processed now and the final enemies are going to be done today (hurray!).

As the title suggests (wow it's something post related) I want to write about the dumb ass AI one, nope rather 4 of the enemies in CC use, if you were so bold to call it AI.

While reading up the docs about the original game I read this:

"goes around objects to the left"

And there are 3 more which go around things to the right.

HA!

I first simply ignored the fact of "going around" and just coded a simple "if enemie hits wall turn left".
cc_ai_00.gif
(ok, I lied, there are some images)

So after noticing my mistake I removed the old code and started to write the one that should allow my enemy to move around things. Sounds easy enough.
cc_ai_01.gif
Oh, that's easy.

"Go ahead as long as there is something to the left, if not, turn left ..."

After a while I really lost my temper and just coded something that could deal with right turns as well, by checking 3 tiles + one, as you can see in the next image.
cc_ai_02.gif
Well that is stupid, isn't it?

Jein, it's a dummy approach. (jein is a pseudo German word, combining "ja" and "nein", yes and no).

cc_ai_03.gif
Some of the common situations, the green arrow shows the next direction
and in "D" shows the use of the 4th check.


In order to simplify (though, yet unoptimised) the checking of the tiles I set up an array of points, holding the offset for each of the checks. To make my life even easier I just numbered the directions (which is used all over the game):
0 = north, 1 = east ...

So the array for 0 (north) looks like this:

this._aTest.push( [new Point(0, -1), new Point( -1, -1), new Point( -1, 0), new Point(1, 0)] );

And because this one should move to the left I added a second array that holds the next direction to go to:

this._aDirNext = [3, 0, 1, 2,  1, 2, 3, 0];

(You might wonder why it has eight entries instead of the needed four, I'll come to that later)
I now could just lookup the next direction I need to face by simply checking with the current direction:

this._iDir = this._aDirNext[this._iDir];

Now, with that in place checking the movement was easy:

private function checkMoveBug ():void {
            
    var strTest:String = "";
    var i:uint;
    var xx:int;
    var yy:int;
    
    for (i = 0; i < 4; i++) {
        
        xx = this._pPos.x + this._aTest[this._iDir][i].x;
        yy = this._pPos.y + this._aTest[this._iDir][i].y;
        
        if (this._refChipsGame.getTile(this._refChipsGame.aMapGame[xx][yy][0]).objProperties.bMonster && this._refChipsGame.aMapGame[xx][yy][1] == -1) {
            strTest += "0";
        } else {
            strTest += "1";
        }
        
    }
            
    switch (strTest.substr(0, 3)) {
        case "000":
// "C"
        case "100":
        case "110":
            this._iDir = this._aDirNext[this._iDir]; // turn to the next dir
            break;
        case "111":
// "A"
        case "101":
            if (strTest.charAt(3) == "0") {
                this._iDir = this._aDirNext[this._iDir + 4];
// this one uses the second pair for "A"
            } else {
                this._iDir = this.getOppositeDir(this._iDir); // this one is used vor "D"
            }
            break
        /*
        case "011":
        case "001": // "B"
            these are not needed because we can just move ahead
            (there is something to the left)
            break;
        */

    }
    
}

The final version has the 4th check removed from the loop and just checks it for "111" and "101".

And because we use an array to store the test offsets, we can make the enemy around things to the right by just changing the values (north):

this._aTest.push( [new Point(0, -1), new Point( 1, -1), new Point( 1, 0), new Point(-1, 0)] );

and changing the aDirNext array to face right:

this._aDirNext = [1, 2, 3, 0, 3, 0, 1, 2];

Vioal. Done.

I hope this is quite understandable (the code is, my writing might not)

nGFX




Wednesday, July 02, 2008 8:45:01 AM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Sunday, June 29, 2008
Preloading with Flex for actionscript projects still seems to be really under-documented. Personally I've found it to be a bit of a joke that you've got to search half a dozen sites to find out how it's done, I mean it's preloading, it's what Flash does.

So I thought I'd add "my" approach here. It's what I'm using and seems to work well, it's been cobbled together by reading through the half a dozen websites, so I'm not claiming it's all my code or my idea, it's other peoples code who are clever than me shoved together.

Let's start at the begining,

package {
    import flash.display.DisplayObject;
    import flash.display.Loader;
    import flash.display.LoaderInfo;
    import flash.display.MovieClip;
    import flash.display.StageQuality;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.utils.getDefinitionByName;

    [SWF(width="400", height="600", frameRate="40", backgroundColor="#FFFFFF")]

    public class Preloader extends MovieClip{
//---------------------------------------------------------------------------------------
// Properties
//---------------------------------------------------------------------------------------
        private var logoClass:Class;
        private var logoClassInstance:Object;
        
//---------------------------------------------------------------------------------------
// Constructor
//---------------------------------------------------------------------------------------
        public function Preloader() {
            stop();
            stage.showDefaultContextMenu=false;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.quality=StageQuality.LOW;

            addEventListener(Event.ENTER_FRAME,mainloop);
        }

//---------------------------------------------------------------------------------------
// Private
//---------------------------------------------------------------------------------------
        private function mainloop(e:Event):void{
            if(framesLoaded >= 2){
                nextFrame();
                triggerLogo();
                removeEventListener(Event.ENTER_FRAME,mainloop);
                addEventListener(Event.ENTER_FRAME,mainloop2);
            }            
        }

//---------------------------------------------------------------------------------------
        private function mainloop2(e:Event):void{
            if(framesLoaded == totalFrames){
//It's all loaded, has the logo finished ?
                if(logoClassInstance.animCompletedFlag==true){
                    removeEventListener(Event.ENTER_FRAME,mainloop2);
                    nextFrame();
                    triggerGame();
                }
            }            
        }

//---------------------------------------------------------------------------------------
private function triggerLogo():void{
            logoClass = getDefinitionByName("PreloaderLogo") as Class;
    if(logoClass) {
        logoClassInstance = new logoClass();
        addChild(logoClassInstance as DisplayObject);
    }
}

//---------------------------------------------------------------------------------------
private function triggerGame():void{
            var main:Class = getDefinitionByName("Main") as Class;
    if(main) {
        var app:Object = new main();
        addChild(app as DisplayObject);
             app.waiting();                        //Call the singleton to kick it all off
                logoClassInstance.dispose();
    }
}

//---------------------------------------------------------------------------------------
    }
}

Just to run through this nice and quickly, the preloader extends the MovieClip class as we're using 3 frames for the game ( The actual preloader class, the PreloaderLogo class and the Main one ( Which is the game itself )).
In the constructor we just do all the stage stuff that we want to do ( Hide that menu ), and then run an eventListener ( Mainloop ) which checks to see how much of the overall game has loaded. If frame 2 has loaded it means how logo is loaded, so we can fire that off ( See the trigger logo method, and below is the PreloaderLogo class )

package {  
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.events.Event;
    
    public class PreloaderLogo extends Sprite {
//---------------------------------------------------------------------------------------
// Assets
//---------------------------------------------------------------------------------------
        [Embed("/_assets/assets.swf",symbol="gywLogoMC")]
        private var gywLogoMC:Class;

//---------------------------------------------------------------------------------------
// Properties
//---------------------------------------------------------------------------------------
        private var gywLogo:MovieClip;
        public var animCompletedFlag:Boolean=false;
        
//---------------------------------------------------------------------------------------
// Constructor
//---------------------------------------------------------------------------------------
        public function PreloaderLogo(){
            gywLogo=new gywLogoMC();
            waiting();
        }

//---------------------------------------------------------------------------------------
        public function waiting():void{
            addEventListener(Event.ADDED_TO_STAGE,logoAddedToStage);
        }

//---------------------------------------------------------------------------------------
        public function dispose():void{
            stage.removeChild(gywLogo);
        }

//---------------------------------------------------------------------------------------
// Private
//---------------------------------------------------------------------------------------
        private function logoAddedToStage(e:Event):void{
            stage.addChild(gywLogo);
            gywLogo.gotoAndPlay(1);
            gywLogo.addEventListener(Event.ENTER_FRAME,waitingToEnd);
        }

//---------------------------------------------------------------------------------------
        private function waitingToEnd(e:Event):void{
            if(gywLogo.currentFrame==gywLogo.totalFrames){
                gywLogo.gotoAndStop(gywLogo.totalFrames);
                gywLogo.removeEventListener(Event.ENTER_FRAME,waitingToEnd);
                animCompletedFlag=true;
            }
        }


//---------------------------------------------------------------------------------------
    }
}

All that's happening there is the class embeds our logo and plays the animation. The waiting() method checks to see if this class has been added to the display list, if we don't wait then you open up a world of pain where the class can't find the stage.
The waitingToEnd method is as simple as it gets, once the animation has finished it just sets the animCompletedFlag to true.

Going back to the preloader class, after the PreloaderLogo class has been triggered we're running mainLoop2. That's just a check to see if the whole game ( ie all 3 frames ) has loaded. If it has when then check for the animCompletedFlag to be true. If it isn't it means the preloader logo is still running, if it is true, then we're done. The game has loaded and our sexy intro anim is done. From there we do exactly what we did before and trigger our Main class ( The game itself ).

The last part of this is the setting in Flex itself. Right click your project and select properties. From there go to the "ActionScript Compiler" options and pass the following arguments to the compiler
flex.png
(click image to enlarge)

And finally after jumping through an insane amount of hoops you should have a working preloader. The logo class can be whatever you want, and there can be more than 3 frames, if for example you want a loader bar to be displayed quickly and then bring in your logos.

*Update - I've posted the source to Operation Cortex, which includes the preloader code which should make life easier*

Squize.

Sunday, June 29, 2008 3:30:55 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Saturday, June 28, 2008
This is somewhat of a rant post (again), although, it might just become some sort of history lesson... we'll see where it ends.

My current game somehow managed to be a real endurance test (as you might remember, if not, read it here), a lot of things that I had never done before, or at least not very often. The combination of the specific genre and the "new" language ... well it took it's time.
As a minor update on this, the game now seems to become more playable by the minute (oh, and yes, I rewrote the damn movement routine, dropping about 50% of the code needed making more stable and of course working - yet again I wonder why I haven't wrote it that way in the first place ... well never know.)

So while coding I started to look ahead for my next project. One of the things I didn't want this time, was to re-invent the wheel, so I had a lok at the game-engines I had coded so far and I discovered one, that never had been used in a game before, but was 100% working. It lacked of course all the nice and shiny things, it was just a working, ugly game - but something a lot of people seem to like (looking around the casual game scene).

The decission was quite an easy one, ignoring the fact that this is just a "me too" game.

Let the ideas come ...

Think, think, think.

One by one the ideas came in, this usually a blend of things I like or like to use, but hey, we're just at the beginning.

STOP.

This time I want something less bloated, slick, clean, minimalistic UI. Once again, I've spend a good time just hunting for inspiration, playing a few of some of the best minimalistic games I've managed to find so far, Tonypa's. They are slick, clean, easy to pick up and don't contain more than the barest minimum of visuals.

Great. Wait. It would be nice if I would add a hint of a background story ...
Oh, and for that I have a great set of visuals in mind ...
Hey, what if I let the player decide what to do next, even though it's just a puzzle game ...

Darn. That's for "less bloated, slick, clean, minimalistic".

Why do I think that this belongs into a game - trying to find the answer.

First of all, I don't like 99% of the mini games that are available in flash. this includes all the "tunnel games", "click as fast as you can", and even praised games like "filler" (which is a nice variation of the qix heme) leave me cold.
I think, it may be, because I've seen their predecessor in various forms on different systems before.
OK, so for me there needs to be some sort of substance attached to a game.

I grew up with a c64 and I collected games (as nearly everyone of this time did), I think my collection had over 2000 games, most of them well, not quite legally optained. But I also owned some original games and paid real money for them. (30 DM, which was a fucking amount of money for a 12 year old school kid).

Anyway these games pretty much defined what I like about games and what not, I like pretty visuals (ok, compared to today those old games look really shit), I like good sound (and I think it's essential for a game) and I like some sort of depth (just clicking and holding for creating a filled circle is it not), a simple form of variation ...

I even tried to add that to "Law of the West", which is a bit shallow, to be honest, but there is some sort of variation in it.

Most of the full price games had at least one or the other, even the low price games from Mastertronic had a lot more game to it than some of the hyped flash games.

Back to pen and paper ... and forget "quick and easy"

Just before I started to write this (and bore you to death) I grabbed a pencil and some sheets of empty paper and began to sketch things out, draw a few charts about the progression of the game and what kind of things I want to add in order to distinguish my "me too" game from all the successfull ones that are already out.

So far I like what I came up with, as I believe I have added some unique things to the core gameplay. Of course it is way bigger than what I wanted in the first place and for sure just as I write this, someone had the same ideas.
To make it even more ... well, use a word you like ... I decided to go with a Pirate theme (still very popular, and although my first idea was to make a third LotW themed game, but I couldn't fit in the ideas I wanted to add)

The basic tasklist so far looks like this:
  • draw a worldmap based on the Caribbean Sea around 1500
  • create a set of outdoor images for the menus and ingame screens
  • maybe create some 3d characters (so it won't look like Myst, ... yet I still want to do my own Myst-like flash based adventure game)
  • draw a map of the decissions a player could make
  • draw the level maps/playfields for the levels (I mentioned it's some sort of puzzle game?)
  • decide on extras that can be used to help the player
  • create a list of nice "medals" (more about that in later post, but right now, play the LotW Pinball to see some).
  • find a way to allow savegames, either over the server, or using a code or shared objects

I'll let you know where this ends, and maybe (if there is interest) I go into detail and post some of the sketches and early renderings.
It seems like this one became a bit more than a simple re-use of an already existing game engine. It also seems that I decided to go a good deal beyond the usual flashgame timewaster - and it clearly shows that I'm nuts. I don't even know if there is money in this one (either as license or (most likely not) as sponsored game (as I had my share of sponsoring madness so far).

stupid me.

nGFX

Saturday, June 28, 2008 1:02:26 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Friday, June 20, 2008
Back.

It's been a while (again) since my last post so this is kind of a catch up of what happend to the game that badly needs to be finished soon.

First let me tell you how much I hate tilebased games.

The current game is my first "real" tilebased game, so this might change after I've finished this one, but for now ... I hate them.

  • Here's a little description of the game.
  • Action and timebased puzzlegame
  • collect keys and items to open doors and avoid obstacles
  • avoid monsters running around
As the game has a built in editor my first (and wrong) idea was to built the map based on the requirements of the editor, which needed to add some additional things:
  • 2 layers, one floor and on "on top" so you could place things below other things
  • connections between certain buttons and their "endpoint"
  • ability to alter the monster order (because monsters can trigger buttons, for instance)
Basically to build the editor was easy (taking into account that it must be easy to use and still allow to edit all aspects of a level), after I did a complete layout in Photoshop I used that as roadmap for coding.

(Did I mention that this is my first AS3 project?), first week

As always the first quite easy project turned into something that's tested my endurance, the switch to AS3 was not as hard as I feared and I found my way around the mass of classes faster than I thought (I think it's because I'm used to .NET which works like this for a lot longer now).

The first few days I spent with converting my toolset to AS3 and setting up (and redefining) my working environment. So it was alot of coding without having something to play with. Then there was a good deal of time "wasted" reading ...

So where is my timeline, week two (or so)

I'm using CS3 and FlashDevelop instead of flex/eclipse, mainly because I can't stand eclipse's behavior and FD looks and feels a lot like Visual Studio, so I feel more at home there.

My first idea was to go with a 1 frame sollution, but this also would mean no pretty preloader, so I got my head around that started with a preloading/main class.
Hunting for a replacement for "this.getBytesLoaded()" I finally came up with this:

        public function Preloader() {
            
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.showDefaultContextMenu = false;

            [...]

            this.addEventListener(Event.ENTER_FRAME, this.onEnterFrame);
            
            this.loaderInfo.addEventListener(Event.INIT, this.initDisplay);
            this.loaderInfo.addEventListener(Event.COMPLETE, this.initApplication);
            this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, showProgress);

            this.stop();
            
        }
        

        public function showProgress(eProgress:ProgressEvent):void {

            var fPercent:Number = Math.round((eProgress.bytesLoaded / eProgress.bytesTotal )*100 );
            var mcProgressbar:MovieClip = MovieClip(this.getChildByName("mcProgressBar"));
            
            with (mcProgressbar) {
                mcBar_00.width = fPercent * 2;
                
                [...]
                
            }
            
            if (this._iState == STATE_NOP) {
                this._iState = STATE_LOADBG;
            }
            
        }

You may notice my excessive use of "this", I know it's not needed, but I kinda like it, as it helps me to see at a first glance what is coded on class level and what is defined in the current method (and it also triggers autocomplete :) ).

One of the very first problems I encounter was the missing support for Movieclips in AS3, not that it is gone but it's not as straight forwards as it could have been.

"Oh you don't need MCs anymore", week two, Wednesday

Of course I do. Damn.
Sure I could code a complex UI and create and place every button, textbox, bitmap by code, but to be honest: WHY? (when you finally see the UI you understand why, I just say more than 150 elements ...).
Though I learned how to get along with it.

"Yes, that looks good", week three

After the main screen was done, it's time to start with the editor.
The layout was done so I could just dive into coding the UI for it, but yet again the next few days were a pain, because theres was just nothing to see.

The game needed a map structure (internally and for saving and reading xml), so I decided to code a map class that not only was able to hold the level's data, but also a methods for handling serializing xml and the map editing methods.

Also I coded a tile engine, which later was converted into the main game engine class. Why? Well, I decided that I don't want to switch to "real" game mode when testing the currently build map (also game and editor are using different tile sizes). So the tile engine is there (because I need it in the editor) and writting an extra game class would have meant to either create a new instance from withing the game or link it in using a reference.

Now I just switch the state of the tile engine and it runs as game and inside the editor.

To run it as "real" game I now just have to pass over the new tilesheet and the game can be run in a different environment. wow.

Fast forward some weeks now, week ... I stoped counting

A lot of code, more code, even more code without being able to play with the result. To be honest I got utterly pissed and depressed.

While coding this game a lot of different flash projects and some dynamic websites needed to be done too, like this: http://akademie.gira.de/ a database driven web based training site, multi language enabled, but in German only right now, so there was a lot of flash and 3D to do, too.

I now can edit a map, but I still can't play it. Time to wander away from flash and write something to save the map ... and wrote this: FileSave.

It's alive, IT'S ALIVE!, this week

Finally at the game is playble in parts (at least in the editor), "in parts" means: the first level can be played, still there are some features missing that need to be added, but I'll add them when I add the original game's first 150 maps (I mentioned it's an official licensed remake, didn't I?)

To get there I needed to convert the nice thought out editor map format into something that can be used to play the game, yes I could have thought about that earlier but hey, it's my first tile based game (Wintertales and Logimotion seem to be Tilebased, but I used it only for the "background, while all movement is done by math).

Yesterday it finally all fell into place and WORKED, the player is moving, can collect keys, open doors ... and the first level can be solved.

After I moved away from frame based and went over to time based movement (read a great tutorial from Jeff of 8bitrocket here).

Hopefully I'll don't forget to return posting about the progress from now on.

Anyway I planed to post a basic overview of the classes and structure used later. (and to be honest I need get to coding :) )

nGFX


Friday, June 20, 2008 12:40:08 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Wednesday, June 11, 2008

Sorry things have been quiet here for a while, I've been busy going to a couple of weddings and making it to 36 without dying ( Quite an achievement considering my lack of doing anything healthy ).

The pinball game still isn't quite gold yet, we're hoping to finally kill it off Thursday. In the mean time whilst it's sitting on FGL we've been included in the new "First Impressions" feature of the site, which I think is a really great idea ( I think it may well still be beta, so I don't want to blab too much about it here as it's not my place to ).

The thing with feedback is culling out the good useful comments from the noise. And by good I don't just mean the "nice work" style comments, but the comments that make you remove the blinkers a little and be objective about the game.

The main concern which has come up is that people really don't like the fact that it scrolls. I find this weird in that I'm used to the 16bit era of pinball games where they all scrolled. It allows for a playfield which is a lot less cluttered and just gives everything a nice sense of scale and scope. I'm just hoping that the slighty broken camera in the version they tested ( Which is fixed now and hopefully always gives you the best view of what's happening and where the ball is going to go ) is the main reason people weren't liking that aspect. If not, then well it's not going to be that popular and that's all there is to it.

grab_lowP.jpg

Yeah, that's a reflection on there.

Another interesting point raised was about the flipper movement, a lot of people felt that there was almost a lag on them, so that was fixed last night to make them more responsive.

Aside from that ( And filtering out the noise like I said earlier, eg "there are not enough features on the pinball board/play area itself (no bumpers/ramps/etc)", aside from those 3 bumpers and 2 ramps you mean ? ) it's just a polarised comments ( "Too complicated", "Not complicated enough", "Instructions too brief", "Instructions too wordy" ) and things we were aware of anyway, such as the animations running too slow ( This was due to developing at 60fps and then having to drop it down to 40fps for the browser version ).

So a bit more love, a couple of bug fixes, a few more assets from Olli, and it's good to go. We just need someone to buy it off us then.

Squize.

Wednesday, June 11, 2008 1:18:50 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [3]  |  Trackback
 Friday, May 16, 2008
This time I'll post a little tool I wrote earlier this week out of sheer lazyness.

My current game comes along quite well, and the built in editor slowly takes shape and while I'm able to create simple levels now I still can't save them because the backend it all relies on is not yet written ...

As I don't have control over the backend I still want to save out my level-data, though as the editor is built in, each new version of the game might bring changes that need to be saved with the map.

I do use Zinc a lot, but imho it's quite a pain to test with and thinking about compiling the swf, switching to Zinc, compiling the exe just to be able to save my data just doesn't appeals to me.

I could do it as AIR app, but yet again, I don't want to dig into it too deep now for just saving a piece of text ...

So what now?

The solution is as easy as it can get: start Filesave, add the Filesave Class to your swf and just use it to save the file through Filesave.

The current version is rough as a piece of coal, but it does what it shoould right now and that's all I care for atm.

filesave_screen_00.jpg
The Filesave UI

"set file" - let's you set the file to save to - no file no save.
"autosave" - saves when data comes in, best used with ...
"overwrite" - replaces the files when saving
"data" - the data to be saved
"save" -  manual save
"clear" - clears data field
"status" - guess ...

And because I think that there are people out there who can use this ...

Filesave_0.1.zip (2,92 MB)

it contains Filesave 0.1, the API and a demo swf. (the first posted version apparently contained a version of Filesave, that didn't work, fixed now)

Have fun, leave comments here, nGFX
Friday, May 16, 2008 10:59:05 AM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [2]  |  Trackback
 Tuesday, May 06, 2008
So "Law of the West" is on it's way into the public now. Final preparations have been made and after *that* long dev. time ... well, I think it deserves some pimping :).

LotW was started back in the good ol' flash 6 days, with some 3d I just made for fun and the first idea was to make it a ***space*** shooter. I think the idea underwent some major changes. It soon became more "Wild West"ish (and later I discovered that I unknowingly adobted the idea of a game I played a lot on the c64 (it shouldn't be that hard to guess the title).

The first major delay was due to my idea to use 3d characters as well, but somehow the first test didn't match the style I had in mind (thanks to BlinkOk from Kazoowee Entertainment, who is the damn best Swift artist I know, for doing a few tests). So the final character drawings needed 2 more artists until the last one finally delivered (that was 2006 I think, thanks to Nephilim).
I got the rough, scanned outlines and started to colorize them in Photoshop with my wacom:

lotw_creation.jpg
The "Lady", from outline to ingame

While waiting for the charcters to take shape, I started coding the game using an event-list system (I'll go into detail once the game is online, because I don't want to spoil all the fun). Basically for each "sequence" I set up an array with a timestamp and an action, as the first entry in the array is the next thing that can happen, I just had to do a iCounter++ and see if the counter has the same time as the first event in the list.
If so, the stored "command" is executed and the entry is removed from the array. If the last entry is removed, a new sequence is created ... easy as 1, 2, 3 ... or so I thought.

Anyway, the "game" was coded pretty quickly, but all the little details and "love" took a *long* time to do (I can admit that all the art took way longer than the coding itself).

To give you something you can look at, here are some screenshots frome the game:
lotw_title.jpg
The (scaled) tilte screen

lotw_highscores.jpg
Highscores

lotw_options.jpg
Options

lotw_bookofinst_0.jpg
Part of the "Book of instructions"

lotw_level.jpg
Level selection

Once it's online I'll post the link here too.

Back to work. nGFX
Tuesday, May 06, 2008 9:26:44 AM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [3]  |  Trackback
 Sunday, April 20, 2008
I've been meaning to post this for about a week, and seeing how today ( And yesterday ) have been spent being really frustratingly trying to get the pinball game to work with the new version of Box2D, I thought I needed a break and should post this up.

Orbs is now a game. Hurray! You can start it, you can clear levels, you can die and it'll take you to the Game Over screen, and then you can run it again. That makes it a game, rather than just a demo, and is a really nice and important milestone to get out of the way.

Aside from getting the basic framework in place, I've added a ton of stats to it, put the medal award code in ( So it slides in nicely down the bottom right to let you know when you've won one ) and added a new baddie.

orbs_grab6.jpg

Those purple bad boys are "leechers". They leave your ship the hell alone, and instead home in on the Orb. When close enough they suck up some energy from it ( The energy bar in the top right there shows that some energy is being stolen ).
When the Orb has no energy remaining, that's it, Game Over. This is the core mechanic behind the game, that it's fun flying around shooting the crap out of things, not so great dying and only having 3 lives. So in Orbs your ship will regenerate so long as the Orb has enough energy to allow it ( Same thing is going to happen with the smart bombs ). The Orb powers everything, and you've got to protect it.

The plan is to have a nice mix of baddies which come after your ship, and ones which just go all out to destroy the Orb. The tricky part for me will be getting the balance right, so you're encouraged ( Or forced ) to move away from the Orb at times leaving it defenceless, rather than just sitting on top of it overly protecting it.

I'm really itching to get back to working on it, but I've got to nail this pinball game as it should be complete in a couple of weeks and we want to get it out there.

Squize.

Sunday, April 20, 2008 5:05:40 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [6]  |  Trackback
 Saturday, April 12, 2008
some might remeber me posting about a sparetime project of mine: Law of the West. It's been quite about it for a good deal of time now, but after a *shit* week I finally got into gear to finish the last damn 5% of it.

The last two night were spent adding the last pice of love to the game, a highscore/gameover screen (the normal gameover screen was in for ages), levels (99, featuring all uglyness I could come up with) and some additions here and there like ingame key-hints when the level starts (this is for all those people who don't read the instructions) and mouse control (it  was designed as keyboard only game).

lThe book of instructions
a shot from the "How to" section (scaled)

Tonight at around 0200h it finally hit gold status, although it took me another three hours to fix (or in terms of flash: work around) some *weird bug*.
Here's a short description, maybe it helps you to avoid it.
LotW consists of two files (game and sound) and I wanted to be able to upload the game and get the sound file from another server, possibly streamed instead of a file reference.

To write the streaming "site" was no problem in .net, so I quickly wrote something that take an ID and returns the swf. I tested it using my local web server - no problem.
Then I uploaded the gamefile to ngfx.de and stored the sound and the streamer here on gamingyourway - guess what: it didn't work.

A quick look at the http headers showed that the file was requested correctly and the size returned was correct, too, but flash returned a solid NaN for getBytesLoaded/Total. WTF?

AH! security! That must be the reason ... ok, changed and added all the "allow *" that was needed and tested again - nope still nothing. Oh well.

To make it short I finally wrote a tiny loader.swf that streamed *both* the game and sound file and viola it worked. F$%&§ knows why.

Anyway here's an image I posted earlier for this game but ...

Meet the gang ...
Meet the gang ...

Right now it's not licensed to I keep a few secrets till then ... but stay tuned (at least I can post about a game here :) ).

nGFX

Saturday, April 12, 2008 4:18:21 AM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [4]  |  Trackback
 Thursday, April 03, 2008
An update to the progress of Orbs is well overdue.

orbs_grab3.jpg

Some big changes. I've re-done the collision routines. They were a simple brute force method ( Checking bullet 1 against each baddie, checking bullet 2 against each... ), now they're based on a grid system. I've done simple sectors before in my old asteroids clone, X, but that was just splitting the screen into quarters, this uses smaller sectors ( So it's more of a grid than just sectors. Moot point I know ).

I've also altered how the particles were plotted. I always wanted to use the Add blendMode as it looks so good ( The Orb itself is a sprite and uses that blendMode ) but the particles are blitted into a bitMap using copyPixels for speed.
I bit the bullet and changed it to use Draw(). Slower ( As it uses Flash's vector renderer ), but I think the visual pay off is worth it. I'm panting to code the smart bomb as it should look great a whole screen full of baddies blowing up in go, with the blendMode it should nearly white up the screen.

With the collisions, I've had to code a bounce routine for the orb, so when a baddie hits it, it moves. Added to that the player bullets now hit the orb and bounce off realistically too ( As opposed to a pong still rebound where the direction just changes ).
In doing this I was badly anal and coded up a faster version of atan2, just to save a handfull of ms
I'm really pleased with how it feels, you can shoot the orb and push it into a baddie to kill the baddie. It feels great being able to move it around the screen by shooting it.

The title screen is in place, and I used papervision for the background. Having never used it before, I was blown away! Really straight forward, and stupidly fast. I now totally believe the hype.
As part of the title screen stuff I've started on the stats page, and got some medals in there ( Achievements with a different name ).

orbs_grab4.jpg

Going back to the collisions, I knew the player > orb collisions were going to be a bit of a mare. I was toying with using Box2D for them, but realised that was overkill for this game.
The solution ? Give the player a shield ( As seen above ) and then it's just a simple circle-circle collision check. Much quicker and much easier. With the Orb already being able to rebound it was just a case of making the player ship do the same. So now you can push the orb around the screen as well as shoot it around.

The shield also sorts the problem of a baddie teleporting on top of you. If that happens, the shield will just kick in, and the baddie dies. Two birds with one stone, great.

There have been quite a few more updates, but time talking about them is time not adding new stuff. I'm hoping to post an alpha here in the next 2 weeks, just to get some nice early feedback.

Squize.

Thursday, April 03, 2008 8:04:56 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [7]  |  Trackback
 Thursday, March 06, 2008
So the menu screen is nearly done - I could resist the urge to do it "right" and add some node-based pathfinding just to display some screen changes.

Today is designh day again, because I have to find a way to do the editor in 640x480 without making it a big pain in the a**. To make this task even easier, I have to fit in the 40 different tiles (which includes buttons and traps) and the 9 different enemy types.

Luckily the maps are only 32x32, but it still means they can't be shown completely at 100% (during play you can see only 9x9 tiles at a time), so I'm going to have to add some sort of scrolling and scaling. Although I think I'm not adding scrollbars and just use space&drag for moving the map, as I use some more key/mouse combinations for the editor (like shift&click to paint a secondary tile (to simulate the right mouse button), ctrl&click to paint into the second layer).

Speaking of the second layer, another neat, yet painfull thing (still thinking of a way to get rid of it). It is in there to allow the hiding things blow moveable tiles, so you can place a fire or a button under a moveable wall tile ... joy.
It may just be a good idea to allow access to the tiles of the secondary layer only if a tile sits on top already ... mhm ... we'll see how that is going to turn out.

nGFX


Thursday, March 06, 2008 1:33:36 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Tuesday, March 04, 2008
No post yesterday, not because I forgot it, but because I had a few other things to do.

So today is day five, I'm finally going to code the menu screens (or as far as I get today), it's going to be a bit tricky, because I don't want to just move in/swap the screens.

My Idea is to have some sort of main-board like grid of connected elements which all can send "redraw" commands to it's neighbour, so when you "start" one node it'll look like flowing energy (I doubt I can explain it well).

Now, instead of just going to the next screen, I want to give a "clean up" command and all unneeded elements hide one by one (following the connections) and then redrawing the new grid from the existing nodes.

Wow - that sounds really - unintelligible.

And here's a picture of our hero (more or less :) ):
cc_posed_01.jpg
(not the finall pose and light, though)

Now lets do some coding ...

nGFX


Tuesday, March 04, 2008 9:25:10 AM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Sunday, March 02, 2008
So I got a bit carried away on Friday. I finished the construction of our new little hero C... (damn I can't tell you his name right now), boned hime up and did a few test renderings ...

And then I got myself an ice cold beer and drank myself away ... nah, I had just one.

I tried to code for a couple of minutes but then thought that it's Friday and I should get my ass out of the door and have some facetime with a few friends.

So on Monday I'm going to pose our new little friend so he can make his apperearance on the titlescreen I'm going to start coding then.

Yeahaaaa!

nGFX

ps: Right now I can't provide an image (same reason I can't give a name - darn - I really would like to)

Sunday, March 02, 2008 4:51:34 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Wednesday, February 27, 2008
OK, I admit I didn't get half as far as I wanted yesterday, there have been far to many distractions on the way, not to mention a big mistake on the design of the character.

Half way through the left leg and the half upper body a test rendering showed: 100% bullshit. So back to pen and paper to get a new idea. If I had a working scanner from where I write this I'd post the scetch, but ... oh well.

Anyway, I had some other projects that needed my attention (in fact they screemed at me), so the first part of the days was wasted fixing some long dead flash thingies (and AS1, too) and after that was out of my system I went back to 3d.

Five hours later (just a few minutes ago) I decided to call it a day and have a finall look at what I have accomplished so far:

cc_chr_00.jpg
A rough OpenGL shot of our hero, head and arms still missing.

One day behind my own schedule, though I hope I get it done tomorrow (arms and head and a few modifications on the breast plate, which looks a bit too stiff imho).

I'm starting a highres rendering now to spot any dents I may need to remove and I'm done for today.

nGFX

Wednesday, February 27, 2008 7:41:27 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Tuesday, February 26, 2008
Inspired by Squize's last posts, I decided to go the same route for this game, too.

Of course I can't tell the name, but I hope to be able to post a screenie now and then. Though, I may say that it will be an "official" port of a (at least it seems so) widely popular game and it will feature an built in level editor to design and share you custom built levels. I still don't have all details about the backend, so when I promise that you can rate other peoples levels and bulit your own favourite levels game, chances are that it might not make it into the final built, but then you still have a game with an editor ...

So this is my "official" day one, I've been working on this game for a few days now (mainly getting a design for the menus and screens) to get "into it".

Today it's 3d day, and I'm building the game's hero. So far I'm done with a leg, the body comes next. I hope I'll be done with him by the end of the day, so I can start building the attractor screens and finally start coding.

some screenies later today, promised.

nGFX

Tuesday, February 26, 2008 12:49:33 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Monday, February 18, 2008
Way back on the 5th of Feb I wrote these wise words,

"We came up with the issue of the lower powered shots just stunning the baddies, and then in theory the player could just sit there shooting the crap out of one baddie to earn a hi-score. Ok, you'd have to be pretty anal to do it, but it does happen"

In less than a day people have worked this out. The hi-score at the time of writing is 1,111,580, that's about 500,000 higher than the number of points "readily" available in the game.

There's a lesson there somewhere.

Squize.

Monday, February 18, 2008 11:35:20 AM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  |  Trackback
 Thursday, February 14, 2008
Just the finishing touches today, although we lost about 3 hours thanks to Flash's security policies ( The tilesheet is externally loaded, and when running on the test server here and the swf on the live one, it failed to load them. 3 hours wasted on that one ).

I guess I'll liven this post up with a screen grab later, but for the time being go and get Loved Up.

Squize.

Thursday, February 14, 2008 4:57:31 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [6]  |  Trackback
 Wednesday, February 13, 2008
So I skipped a day. I'm pretty surprised it was only one.

Yesterday was a bit of a painful one, I guess that's why I couldn't face writing an entry about it.

It was a lot of skinnning up as I was getting new assets through out the day. It's always a double edged sword, on the plus side getting great new assets really gives you a boost when you're getting a bit sick of the game, it makes it feel new and fresh and complete.
On the harsher edge, it's very rare that you get every asset just how you coded them, so there's always a bit of jigging around. A good designer knows they're way around Flash, and Ian whose done some great work on this, has made it as pain free for me as possible.

At this stage of a project, the vinegar strokes, you can't hide from things. All those boring / tricky / hard / nasty jobs that you've been putting off have to be tackled. The original assets were delivered as vectors. The head seperate from the body, that kind of thing ( So for example you can just have the head tweening over 5 frames, whilst the body animates over 20 to get a complete running cycle in there ). What the original artist had done was to draw them huge, and then just scale them down to size. That's all cool with vectors, but not so great with bitmaps.
Basically it meant exporting every single vector frame ( Again ) to a bitmap, and then re-sizing them all ( One of the baddies was over 1000 px wide, each frame ) and then batching them with Fireworks to 8 bit png's with alpha blending ( The best thing ever ).

Drawn out, boring, but so worth it. The game dropped from around 2.8meg to 1.7meg.

Today, the big push. We wanted it live by five. If you don't want to know the outcome, don't look for a link on this post.
First thing, and a bit late in the project but it's been really condensed, was a To Do list. Just simple and quick done in Notepad. First thing this morning I was looking at around 12 things that needed attention, from the simple ( Alter 1 graphic ) to the things you don't want to be doing on deadline day ( Fix major, fatal, bug on the horizontal collision ).

We managed to burn through it, although we spent around 4 hours getting the sfx in and working nicely ( It does sound really good, it all fits well ). Top tip, don't fall into the trap I always do of thinking the sounds will only take an hour or so. They never, ever do.
Lot's of little things were tidied up, things which can't be avoided, and it was a case of knocking one thing off the to do list, but fixing another 3 things that I'd spotted whilst working on the original task.

Well, where's the link ? I can explain... We planned to have the game done by 5, but it then slipped to the game done by 5, with an extra hour to put the hi-score and mochi-ads code in.
We got the game done by quarter to 6, and then on to the hi-scores. I'd been avoiding these, as they're a pain in the arse 99% of the time, and mainly 'cause mtasc wouldn't compile them ( It's a component developed by gimme5games ) so I didn't want to revert back to using Flash until the very end ( mtasc compiles the game on average under a second, Flash with all the sounds in it, makes that about 20-30 seconds ).

I had a bit of a mare getting them working, but it wasn't too dragged out. Then on to mochi-ads, which I've never done before. In the mean time the game was being tested briefly, where a couple of bugs were thrown up.

It became time to admit defeat, the assets for the site weren't done, so it wasn't going to go live tonight anyway. The game needs more testing too, it's only been really tested by the people working on it, and you need a fresh pair of eyes.

Very gutted to be honest, it sucks donkey to really kill yourself to hit a deadline only to fall flat on your arse. And on that note I'm going to call it a night, and tomorrow is a new day ( A love day no less ) and there will be a shiny new link on here.

Squize.

Wednesday, February 13, 2008 10:19:41 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Monday, February 11, 2008
Joy, Monday so soon.

Today was a bit of a reviewing where we're at day, as the game's producer and designer were back from Amsterdam ( Some casual game conference as opposed to a drugs fest ).

Got the locks ( Although they're now called switches as locks wasn't the best term for them ) in. There's a bit of an issue about the player collision with them as the original engine wasn't really designed to be pixel perfect for things like this, and it was a bit of a mare connecting each switch to each row of tiles, although I'm pretty pleased with the solution ( Short version. Each time a switch or bank of invisible tiles is plotted into the map they're given a "group" value to tie them together. When the player triggers a switch by shooting it, it fires off an event with the switches group number, which the invisible tiles are listening for. If it's a match, sweet, the tiles stop being invisible and appear. Quite simplified, it took a good hour or so for me to get my head around the best way to link two different objects like that without being able to link them via the map data ).

With a designer on board full time now, there have been some changes, the main one being the stage size, and therefore everything has been moved around to take advantage of it, which has thrown up a couple of problems.

Also we've got the first 3 levels in the bag. It's going to start nice and easy, but it's looking like the difficulty curve may be a bit sharper than we originally planned, which isn't a bad thing.

Finally, dropped in the gimme5 high score component. It meant ripping out some existing code 'cause I didn't realise the view hi-score option was a page re-direct rather than in the game ( Which I'm not a huge fan of to be honest ).
mtasc seems to be not liking it, so I can either hunt around to try and find out why, or just put the hs stuff off until right at the very end and then just publish the game via Flash rather than mtasc ( Which just kills my workflow, so it's something I'm loathe to do, so I'll put that off until after everything else is sweet ).

That's it, getting closer.

Squize.

Monday, February 11, 2008 9:13:08 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Friday, February 08, 2008
A bit more of a constructive day today, good to end the first full week of working in the office with.

All the baddies are in now. The 2nd flying one ( Wasp ) that I mentioned yesterday, and 3 types of ground based baddies ( One just moving back and forth, one charging at you, and one jumping around ).
Also all their mutated states are done, some better than others ( It's really difficult having limited graphic resources trying to come up with something more than just making them move / shoot faster. To be honest, I failed. They do just move / shoot faster ).

There are a handful of bugs, but only tiny anal ones which I notice and they really burn me.

Left to do is the "locks" which when shot will turn on previously invisible platforms, and that should be about all the actual content done, so hopefully by the close of play Monday ( Which is the 11th, deadline is 14th at latest, idealy before, so the game can be pimped out ) all the game related stuff should be done, so it'll be a case of adding sfx / extra images / love / making sure it works with the levels which are to be designed for it, and any ad / hi-score stuff which will be needed.
In a perfect world it'll be gold Tues, ready to be pushed out the door first thing Wed with a day in hand. That's the perfect world plan anyway.

Squize.

Friday, February 08, 2008 5:32:31 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  |  Trackback
 Thursday, February 07, 2008
To quote from yesterdays post "I'll be adding the rest of the baddies in one big hit, which should be fun."

Oh dear.

Today has been spent adding the mutated Rabbit ( I'm 35 and writing phrases like that ). I was struggling with what to do with him, as I've been told we've not got any budget left for animation and we've only got running frames, so... he now fires lazer beams from his eyes. As mutated rabbits do.

I think I've written far too many shooting routines as it didn't take long at all ( Worked first time too, aside from some alignment issues ).

So pushed on and added a bird baddie, who throws stones at you. That was quite straight forward too, until I decided it may be cool that the stones he throws ( Drops ) should detect platforms and bounce around a bit if they hit one.
Not exactly rocket science to get working, but took longer than I'd planned to get it looking nice.

That's about it for today, which seems bugger all really. I've got another flying / stone throwing baddie to do, which hopefully is going to be mainly copy and paste, and then I think 3 more baddies left, so they should be done tomorrow.

The game's really hard now, as on my test level I've got all the baddies tightly squashed in together for easier testing, and I'm looking forward to having some final levels designed that play to the games strengths.

Squize.

Thursday, February 07, 2008 5:52:05 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Wednesday, February 06, 2008
Following on from yesterdays post, this one is going to be a little bitty.

Yesterday before calling it a day I dropped in another baddie and wrote the mutation routines for them both, so if you shoot the hell out of them without trapping them in a heart they'll turn bad, and be even more intent on killing you.

Today has been more of a consolidation type of day ( Read, boring but necessary ). Dropped in the game over screen animations, and the pause mode ones too.
Ripped out the last remaining presentational assets from the last game, so the hi-score input / display is reskinned now.

Major thing was getting the game to realise when a level has been completed, and bump it on to the next one. Got held up for a while as the Toxic engine was designed for a different tile sheet for every level, whereas this game will just have the one ( Although all the map / object data is still loaded externally ), but got it after about an hour of swearing.
The game also knows how many levels there are now, so the game complete screen has been dropped in and works too.

All quite boring, but it means that it's passed the milestone of being a real game now. Not too much fun, and still quite rough, but a game it is, and that's always good.


Did the preloader too, which involved coding on a movieclip, which is totally alien to me these days, and felt very very old school, but it's only a simple "duplicate lots of clips then move them" routine, about 15mins and it was done.

And that's about it. Tidied up the player dying routines and fixed a bug where the camera wouldn't follow your body correctly if you were killed and fell off a platform. Bonuses at the end of level are all in ( Re-used from the last project, which stole the idea from the JBJ Sisters way back ).

Tomorrow I've got a couple of bugs I want to get out of the way ( If I don't manage it in my last hour today ), and then I'll be adding the rest of the baddies in one big hit, which should be fun.

Squize.
Wednesday, February 06, 2008 5:00:48 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Tuesday, February 05, 2008
Thought it may be a nice idea to do a bit of a diary thing on here for the current game under development. I'm not sure how long I'll stick with it, but let's hope it's fun whilst it lasts.

The new game ( Let's just call it "Another NDA protected game" for the time being ) is based on the Toxic platform engine for the platformer thats still dragging on behind the scenes.
So getting the basics in there and running was nice and easy, strip the odd asset here, remove the odd class there and it's up and running. At present it's still a bit bloaty ( 1.7 meg swf ) but there's more to come out of it, including a lot of sfx.

As this is a themed game, for Valentines, it's a boy chases girls heart premise, based in a vertically scrolling platform world. Bubble Bobble and it's sequel, Rainbow Islands, have been strong inspirations for this project.

K so it was started last Monday, and we've got the title screen / loading screen / pause screen and game over screens in place. The first baddie took his first steps yesterday, just a nice and simple back and forth bad guy.
Last Friday I was tied up installing Eclipse etc. on a new machine ( I'm office bound til the end of June, so all the joy of travelling in London, and none of the getting up whenever I like that was the beauty of freelancing at home ) so I got very little done, but made a start on the shooting ( Hearts, what else ).
Yesterday after the baddie was put in there it was then time to enable you to shoot him, which worked a treat. The longer you hold down the fire button the bigger your shot. Little shots just stop him in his tracks, but if you save up a max shot you can trap him in a heart.
From there a collision routine was added to test for pushing the heart ( Using a couple of nice and simple circle-2-circle checks ) and a further one for jumping on the heart, which will make you jump that little bit higher.

( A core feature of the game will be to trap baddies, move them whilst encased in a heart, and then jump on them to reach those out of the way platforms / collectables )

Today so far has been spent giving the bullets a range. We came up with the issue of the lower powered shots just stunning the baddies, and then in theory the player could just sit there shooting the crap out of one baddie to earn a hi-score. Ok, you'd have to be pretty anal to do it, but it does happen ( Some people just love seeing their name in lights on a hs-table ), so we've decided that the more powerful the shot the shorter it travels before floating upwards and exploding ( In a shower of hearts naturally ).
Joy of joys first time of testing I stood on a platform beneath a baddie and fired a big shot, for it to rise up and trap the baddie above me. Things like that never ever work first time.

It's not really fixed the problem of anal gamers just shooting away, it's just opened more game play avenues. We're thinking it'd be cool that if after x number of shots the baddie mutated, like in the old Mr Do! games for anyone as old as me, so that's what the rest of today is going to be spent on, making the cute baddie Panda a nasty sod when he gets angry.

Hopefully more tomorrow.

Squize.

Tuesday, February 05, 2008 2:02:28 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Tuesday, January 01, 2008
Well I've been freelancing for over a year now, and GYW must be due it's first birthday, and what with it being the start of a new year I thought it'd be cool to look back at what's gone before so we can look to the future.

warmbeer_grab.jpg

The Day of the Warm Beer. One of my favourite games, I was just given so much freedom on this, and one of the few games that I'm really gutted with didn't have more time with 'cause there was so much more we could have added.
I'd do a sequel tomorrow if I could.
( One quick thing to note, the boys at skive had to alter it, click tracking I guess, so the correct font isn't shown on the sat nav and the arrows pointing to your friends don't tween correctly. )

polarity_grab.jpg

Polarity. I love parts of this, and really dislike others. Should have been better than it is, but it's still pretty impressive.

greenlight_grab.jpg

Greenlight. A really aggressive deadline for this so it was a stressful development ( I was also finishing off Polarity at the same time ). Not my thing to be honest, but I think what we did we did well. It's recently had some more levels added to it, but I was tied up so they were done internally at Skive.

thinkDrive_grab.jpg

Think & Drive. My first job with Morpheme ( Before starting on the Phantom Mansion games ). It's still sitting around waiting for the client to supply a final bit of copy before going live. Feels a bit dated now ( It's been gold over 6 months ) but it's still fun, and it was great using the mouse to control a driving game.


sol_2.jpg

Signs of Life. Epic huge project, although I really had next to no input. A pay the bills job for me.
I'm not going to link to it as it's UK locked due to it being a BBC project ( And therefore funded by UK licence fee payers ). I think 'cause of that it's recieved a lot less attention than it deserves, which is a crime.

pm_screenGrab.png

Phantom Mansion(s). A very difficult and drawn out development, but we're there now and it plays really well. I've just all but finished the next chapter ( Blue, which is number 5 I believe ? Starting to blur a little now ) so that should be out before the end of the month.
( Some of the early chapters have an issue with the loader frame work, if it gets to 3 hands on the preloader and just sits there, hit F5 and it'll work fine ).


FF_logo.png

Model City. Bit of an emergency job to help out a mate, I re-coded Fuel Factor-Y from scratch in 8 days ( I think that includes the never ending supply of amends ) as the original game source we were given would have been too much work to reskin and add the additional features.
Also did the code for the model city itself ( The loading Hub ) and various bits and bobs on the other two games.
Not the most fun project I've ever worked on.

grabFinal.png

Crazy Balls. Just a rebrand and re-release of an old game to see how it would fair on Kongregate. It died on it's arse.

GiftShopButton.png

The Game of Life. This was actually being developed when I was working on Signs of Life ( And "Golden Balls", which still hasn't been released and I think I'd be badly busted if I even posted a screen shot of it ).
First time as a project manager, and one of the best things I've ever done, and great working with Olli and Marmotte on it. There's more than enough posts about it on the blog so I'll leave it as that.

And that's a years worth of development. Hopefully when Olli stops being lazy and taking time off he can post some of his goodies too.

Coming up we've got the platform game ( Which I'm really proud of. It's on par with GOL in terms of love and quality ), the continuing Phantom Mansion games, Orbs and Olli's got a great old school game that we've been commisioned to do. All good.

Squize.

Tuesday, January 01, 2008 3:24:16 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Tuesday, October 30, 2007
In a recent comment posted here I was asked about the slopes in the current platformer, and I promised I'd go over it, so here it is ( Albiet slightly rushed and with no nice diagrams, deadlines and all that ).

In a tile based engine it's fairly simple to work out where the position of the sprite is in relation to the tile he's standing on. So as you move over a tile you're updating the x position which is obvious enough.
Also usually with map data you have an attribute value / byte for each tile, again if you've worked with tiles you're with me so far.

To simulate a slope easily you have an array of y positions for the sprite. In my case I have 8 values for every sloping tile, as the player moves at 4 pixels per frame, and the tiles are 32px wide, so it's 32/4 = 8 possible positions for every tile on the horizontal.

Let's say our slope looks like this ( In array form )

[0,2,4,6,8,12,14,16];

If we're at position 0 on the x of the tile, ie the left hand side, we read the first value in the slope array, in this case 0, and we decrease the sprites._y by that amount ( Decrease 'cause we're moving him up ), so the next step will make the sprite 2 pixels higher up the screen than he was last move and so on.

Above I mentioned using attributes, this is how I get an offset into the array of slopes ( They're just stored as a 2 dimensional array ). If you didn't use an attribute in the map data, just used the tile number, then you'd need to have an array for every single tile ( Where the vast majority would be flat ), which is a hell of a lot of work for no reason, and a waste of resources.

So again we're stepping on our tile, and it's attribute is 1. We know to look into the slope array at attribute-1 ( Arrays start at 0 ), which gives us our first saved slope value, and from there we can get the correct y position for each step of the way.

Simple as you like, hardly any real cpu overhead, and so far with what I've been working on it seems to cope with any angle I've thrown at it. If you wanted to add more realistic movement ( So the sprite stuggles up a hill, sprints down it ) you could store another array with the players max moving speed for each position and add that to the overal speed.

Squize.

Tuesday, October 30, 2007 6:23:32 PM (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  |  Trackback
 Monday, October 22, 2007
Worked on Orbs over the w/end, and had to re-organise a ton of stuff ( I'm still finding my feet with this as3 lark ).

The particles worked by using copyPixel to plot them into a bitmap ( Blitting, like the good ol' days ) and then using colorMatrixFilter to fade them down every couple of frames.
I've really been wanting trails on the baddies too ( I want to use the add blendmode, but I think that's going to be too much. That may just be reserved for the Orbs themselves ) so this major reshuffle saw the baddies being changed from sprites to bobs ( Blitter OBjects ) again using copyPixel.

Seems to be running a lot faster for the change, and looks a lot better. Also 'cause I'm fading down the whole bitmap that they're being blitted to I don't have to worry about any kind of clearing up or damage maps. Cool.

I'd been meaning to try blitting sooner, but I was concerned about losing things like hitTest and rotation, but at the moment it's performing nice and fast and I'm hoping I can come up with a good way to cope with the silly amount of collisions I've got planned ( At present I'm looking at doing it sector based using circle to circle checks ).

Next step is to drop the collisions back in and see how the engine copes with that, and then some animation ( So it'll be an animated rotate ).

It's all looking pretty good right now, I'm really happy with it.

Squize.

PS. Next post, something on slopes.

Monday, October 22, 2007 3:25:33 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Friday, October 19, 2007
A little update is well over due, so here's a couple of grabs of two current projects.

ts_grab1.png

A platform game, which I'm afraid is covered by an nda, but despite looking nasty with that placeholder art, it's coming along quite nicely. I'm still really buzzing with this project as it's my first ever platform game, and I'm just planning on over delivering by a lot to make it as good as the time will allow.
The scrolling is in and working ( Although the vertical panning is a bit out ), collisions are working just how I wanted ( The player to baddie collisions worked perfectly on the first compile. I mean, when does that ever happen ? Somedays it's almost like I'm a proper coder ) and it's all coming together like an orgy. Nice.
I'll be posting more about it as it develops, within the boundaries of a nda anyway.

orbs_grab1.jpg

A picture paints a thousand words and all that, so I'm not going to go too much into the gameplay. My first as3 game, and I'm nearly getting to the point where I'm not getting a compiler error just by being in the same room as Flex.
AS3 is funny, it gives you so much power that when you try something and it runs slow, it's like wtf ? A good position to be in though.

I think "Orbs" is my first personal project since Crazy Balls, which from memory originally went live in 2004.

Squize.

Friday, October 19, 2007 4:44:04 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [2]  |  Trackback
 Thursday, August 09, 2007
The current project, "Phantom Mansion" is a port of a mobile phone game.

When the site actually goes live you'll see ( If your interested ) case studies for all the projects. The case studies are written in a more professional style, outlining the thought processes as well as the development cycle.

They're glossy and nice.

When it comes to describing Mansions' development, I imagine I'll write something like "A difficult development process due to adhering to the existing design restrictions".

In real life, Mansions' development has been a total cunt.

This is why I've been awol from the blog, and I owe a dozen people a dozen emails ( Sorry ). Indulge me why I vent my spleen a little. The game is  I guess what would be called an "Arcade Puzzler" and as a game it's pretty sweet. It's just that it was designed for java, and so doesn't play to any of Flash's strengths.

At present I'm in the hell that is depth sorting. It's not something I ever seem to do too well, just another black hole in my mind when it comes to coding, but this isn't the usual swapDepths based on the sprites y position. Nope, that would be far too simple. The game has bridges that you can walk over and under. And the baddies can walk over and under. And you can push crates ( You know the score by now ).

Not too harsh. But, and this it the beauty of it, all the sprites are offset on their y position by around 10 pixels ( ie, the image is placed at -10 on the y axis ). This was because in the original it allowed for simple depth sorting with some of the tiles in the game ( So the sprites wouldn't have to be behind certain tiles, so you don't need to worry about sorting for that ). Easy old school trick that surely could never come back to haunt you ( And no, that wasn't a pun ).

So you've got a bridge, and you put it in a higher layer than the sprites, so you can walk beneath it. When you have to walk over the bridge, simple and sly, just have a copy of the same sprite in a layer higher than that, and _visible=true and it's job done.
But, hang on, the sprites are offset. So although they're 32x32 pixels, the same as the tiles, they actually cover the tile above. Surely that means that walking infront of a bridge would lead to the sprites top 10 pixels ( Roughly a head's worth ) being obscured.

Ok, not a problem, we just check that and turn on our higher up copy of the sprite and it's all fixed. Internally every sprite has a zdepth var, so we know what "level" it's on, so you can walk over a bridge and a baddie walking beneath you can't kill you ( It wouldn't be the fairest of games otherwise ).
Where were we ? Oh yeah, at the foot of a bridge bump the sprites level to 1 and display the sprite in the top layer. Now if the sprite is to the left / right of the bridge we shouldn't do this, so we don't. I'm building up to the kicker here. Let's just push that crate along. Oh arse, it's over the bottom of a bridge, let's knock it's level to 1 and blah, blah, blah. The player's sprite whose just pushed it there though, he's still on layer 0, he doesn't know anything about the bridge. So what happens when he goes to push the crate, which is higher than he is ?

pm_bugGrab.png

There's the bridge, tinted orange so I can see it's in a higher layer. The crate which overlaps it tinted green, again so we can tell it's not in layer 0, but look at the Hector ( Our hero ), he's not green 'cause he knows no better.

This is part of why this is a "A difficult development process". There are way more joys that I could share, but I'll hold fire. No one wants to read about someone bitching about their job.

Squize.

Thursday, August 09, 2007 6:27:44 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, July 26, 2007
How pure is pure oop, how usefull are design patterns and how to abuse asBroadcast?

Well, for the current game I'm bound to f8/AS2 because the client's audience is still mostly on f8 and the attempts to make them update the player greatly failed and resulted in a lot of "what is an update of the flash player", "what is a flash player" and "I don't know how" emails ...

The game currently uses my usual structure, that is a single class for the game and some classes for UI, sprites, tiles ... I usually made the game class "LMGame" (LM for the game's name) a singleton, but I wondered if that would be a good practice after all.
(You might guess it, this is a more or less philosophic question.)

I wanted to reduce refrences and singletons to a minimum. (Squize wrote about the problems earlier)

So far I came up with few different methods for accessing the LMGame class from various other classes during the game ...
If needed I pas a reference to the LMGame / needed class but you must admit that this feels rather clumsy.
For the Sprites however I didn't want pass a reference to the LMGame class just to say "Hello" or "I'm dead" ... so I tried a rather unusual way for sprite -> game communication:

While the game has a list of sprites and could call functions directly, I decided to rely heavily on asBroadcast.
I installed a stack (FIFO), to pass values if needed and tried if things were working like I expected ... and they did ... :)

A sprite is moved with this._asBroadcast.broadcastMessage("onTickEvent"); (from the LMGame class' onEnterFrame) and if a sprite dies it places it's id into the stack and calls this._asBroadcast.broadcastMessage("onSpriteDie"); (which is triggered by the LMGame class).

This might seem overly complicated but it really "looks" wonderfull in code and it saves a great deal of thinking, too.

As this is just a "try", I'm not sure if it's going to become very usefull, but I just like trying new "ideas" ...

nGFX
Thursday, July 26, 2007 2:09:01 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, June 14, 2007
Long time no post, so I thought it might be the time to do so again ...

While still working on the last GOL game ("The Day of the Triffids"), my mind starts wondering off to the next big project, the "logimotion" game.

I do dimmly recall that when doing the Wintertales/Deserrunner game I said something about explanation, but I guess it somehow slipped through just waiting there to be recalled now ...

So here we go:

Time based movement and tracks/tiles ...

While doing the engine I came to the point where I had to move the sprite over the player created tracks, two ways came to mind:

a) write some fancy stuff for each tile, using the sprite and offset it's coords according to the need of the tile.
b) write some fancy stuff that works whth each tile, using some other approach.

I decided to try the latter one.

What bothered me with the first method was that I had to map out coordinates or tween the sprite along the tracks which somehow wasn't what I wanted.

The second method wasn't that clear. I needed to find a way to move the sprite from the starting point of the tile/track to it's end ... after a few pointless tries I thought that I could just do it time based instead of position based.
This proved to be a very easy and re-useable way.

dt_track_00.jpg
screenie of the car in motion, showing the track, too.

As the car isn't shown top/dow, there needed to be some sort of animation and we wanted to be able to move with different speeds, too.

My first task was to invent some sort of naming convention which helps me to sort the different tiles and tell the code *what* this tile does without adding to much fuzz to the map.

So I decided to use a for digit code like 0011 for a corner from west to south, giving each direction either 1 for "exit" and 0 for "no" exit.
Then I decided to use "easings" to move from the starting point of the track to end point of the track. Moving a stright line (0101, or from west to east) would just ease the x value linear in say 16 frames (and because I had 16 animation frames ... you guess right).

This is what I stored for the tile:

this._tile_array[22] = {sx: 1, sy: 1, t: TileEngineClass.TILE_TRACK, f: "t_0101", d: "0101"};

sx/sy: size
t: tile type
f: frame in the tile mc
d: direction information

And this is what the player sprite "knows":

this._track_array["0101"] = new Array();
this._track_array["0101"][1] = {sx: _x0, sy: _y1, ex: _x2, ey: _y1, fx: EaseUtil.easeLinear, fy: EaseUtil.easeLinear, nd: 1};
this._track_array["0101"][3] = {sx: _x2, sy: _y1, ex: _x0, ey: _y1, fx: EaseUtil.easeLinear, fy: EaseUtil.easeLinear, nd: 3};

sx/sy/ex/ey: start coords/end coords for the easing
fx/fy: easing method for x/y
nd: the new direction after reaching the end point, used for corners mainly.

The sprite knows which direction (0-3, according to the 4 digits of the name) it's moving, the animation it should use ("0101" + frame for the current time) and it's time.

If the sprite reaches the endpoint of the ease, I can look up the next tile in the map array (because if the direction of the next tile is 1, I take the next tile east of the current tile).
If the next tile is empty, well the player creashes.

Easy, isn't it?

Here's the data for a corner:

this._track_array["1100"] = new Array();
this._track_array["1100"][2] = {sx: _x1, sy: _y0, ex: _x2, ey: _y1, fx: EaseUtil.easeInSin, fy: EaseUtil.easeOutSin, nd: 1};
this._track_array["1100"][3] = {sx: _x2, sy: _y1, ex: _x1, ey: _y0, fx: EaseUtil.easeOutSin, fy: EaseUtil.easeInSin, nd: 0};

In order make it faster I just reduce the time needed to get from start to end, though it's a good idea to use something that can be devided by 2, so the animation isn't messed up

You can see it in action: here (German version, though)

Back to the Triffids ...
nGFX

"Some people are heroes. And some people jot down notes."
        -- (Terry Pratchett, The Truth (us, de))

Thursday, June 14, 2007 11:56:30 AM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Friday, April 27, 2007
Ha! The title says it all, yet again a text only post ...

While working on the current game (the same project Squize is working on, see his last post), I needed way to be able to paint an area in a real life fashion (that is, the paint on the brush runs out just a few centimeters before the end of the wall).

I must admit, that I didn't have much play with f8's BitmapData before, I just don't needed it. Until now.

I just hate it to get into something "new" in the middle of a project, but unlike some of Flash's other new things BitmapData is fairly easy to get into. Except the part where you start to mess with matrixes. I had some great examples which showed a lot of the stuff I thought I need, but I just wasn't in the mood to dig into using matrixes for creating the desired effect.

But there is hope ...
Using 3 BitmapData objects, 2 PNGs and copyPixels with alpha ...

Part of the code:

var bmpAlpha:BitmapData = BitmapData.loadBitmap("brush_shape_and_alpha.png");
var bmpBrush:BitmapData = BitmapData.loadBitmap("paintpattern.png");
        
// mod alpha
// iPaintAlpha is a value from 0 (paint it) to -255 (paint nothing)
bmpAlpha.colorTransform(bmpAlpha.rectangle, new ColorTransform(1, 1, 1, 1, 0, 0, 0, this._iPaintAlpha));
        
this._bmpPaintArea.copyPixels(bmpBrush, bmpAlpha.rectangle,
    new
Point(this._xmouse, this._ymouse), bmpAlpha, new Point(0,0), true);
      
this._iPaintAlpha--;
      


Et viola ...

Instead of using some matrix stuff, I just "alpha" the alpha chanel mask with a ColorTransform and use this to copy the "paintpattern" into the painting area ...

I'll upload an example file once I've reached my current milestone ...

nGFX

Friday, April 27, 2007 12:25:28 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Tuesday, April 24, 2007
The controller is well under development now, and over the weekend I hit the first real snag(s).

In the good old days when as1 was king, you'd create an movieclip and load your external swf into that, and then just call a function directly. Nice and easy.
In the slightly meaner days of as2 it's a bit trickier. Let's load the swf in, now where the hell is the main class that I need to get to ? Arse.

Now I'm sure there is an easy way to do it, a way I've totally missed, but this is the solution I've come up ( And it's as long winded as you like ).

I've made a CrossSWFInterface class, which the controller brings in and creates a new instance of. Now by being cunning I know that packages/ classes are placed in the _global name space when they're created. So, each loaded class just passes it's entry point singleton to the CrossSWFInterface class via _global, eg
        _global.Interface.CrossSWFInterface.setLoadedAPIClass(gameControllerObj);
And because the controller swf is the first one loaded, I know these methods are going to exist in _global by the time the loaded swf sends it's goodness to them.

Then by using static properites in the CSWFI class, the controller class can get all the info it needs from the loaded swf, and visa versa.

Now I'm sure there's got to be a easier, cleaner way, but it escapes me and we're badly up against the clock on this project, so it works and I'll happily admit I'm a dumb arse when someone explains how to do it correctly, but until then I'm happy with this approach.

I did mention snags at the start didn't I ? In my vain attempt to be a grown up Flash coder I use mtasc ( Which is so sexy ). The one issue with it I found this weekend was that you can only ever have one entry point to a swf ( ie, mtasc expects a class called "main" to be there, it's what it calls to run the code in the swf ). You can't change it to anything else, that's set in stone.
This is all cool normally, but I want to create seperate packages within my project file for the games themselves, but I can't have a different main class for each of them ( eg, main_game1 won't work. mtasc just wants main and nothing else will do ).

Cosmic.

But this bad boy came to my rescue, hamtasc. Basically it's a "hacked" version of mtasc which allows you to define the entry point. Never has something so out and out geeky made me so happy.

I'm hoping tomorrow to have the controller in a useable state so I can start focusing on the game I've got to do ( "Souper Bowl". Tell me that's not genius ), so it'll load in and hand over control to the game etc.
I'm getting so close to doing something fun...

Squize.

Monday, April 23, 2007 10:01:17 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Tuesday, April 10, 2007
Inspired by a recent thread on fk's game forum here's a brief description how the day scene was actually built:

Usually it starts with a *very* simple sketch, whith very littly detail. Most 3d artists I know do extensive and detailed drawings, but for me it works best to directly do it in 3d.
twh_070410_08.jpg
more ugly than beautiful

Once I have this I start by modeling parts of it as single object that I later can link into the final scene, this time it's only the tower:
twh_070410_01.jpg twh_070410_10.jpg
Simple outline rendering and the textured version.

A detail of the main tower mapping:
twh_070410_09.jpg
3584x3584 px ... now tell me that size doesn't matter.

Now I start composing the scene, here just the linked tower with the landscape set up. In the foreground I've placed some noised up spheres to be used as rocks.
twh_070410_03a.jpg twh_070410_03b.jpg
Landscapes in plain grey and with some basic textures applied.

Now adding some depth:
twh_070410_13.jpg twh_070410_04.jpg
Added 2 trees for the foreground (846,419 polygons now) and finally with all the trees, grass, bushes
and textures applied (now 383,890,620 polygons).


Final step: adding real light and shadows and setting up the atmosphere ...
twh_070410_05.jpg
Preview rendering, you can see the result in the previous post ... (or click here)

After the scene was done, I decided to add two wizards to the final image so I quickly built a low poly one from this sketch (done by Chrsitof) and did two very simple texture maps:
twh_070410_07.jpg twh_070410_14.jpg
Sketch and the wizards placed in the scene.

Done!

nGFX.
Tuesday, April 10, 2007 2:10:28 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Monday, April 09, 2007
As promised in an earlier post here two (still working on a third one) stills from the intro of my "private" game:

twh_070409_01.jpg
Welcome to the Secret University, home to many soon to be wizards.

twh_070409_00.jpg
What now looks like a friendly night, ...

Both rendered at a resolution of 5120x2880 px (ugly to lose all this detail in those resized images, though), taking about 19h rendertime each. My plan is to use the way smaller version (my hope is to get it rendered at 480x270 (16:9) in a moderate filesize, using some 250 frames per shot (a day shot, a night shot and the secret third one)  in order to tell the story. Some earlier tests have shown that the animated clouds, the moving sun/moon and some wind moving all the grass and the leaves simply looks incredible. Yep and I know this is a bit much for a flash game - but hey - one should have dreams.

I hope I get the third shot done by Thursday this week and then start to lay out the animation.

Oh, you might noticed that this isn't quite the way it works usually (first doing a *lot* of artwork and later do the game), but this time I decided to do all the frontend stuff first and then add the game, call me stupid, will ya?
Ok, one of the reasons is that I needed to get my head away from flash while working on the code for the client's games and applications, and doing 3d is the way to keep me sane at the moment.

While typing this, I forgot to mention that the game as a name now, though this is for the next post.

nGFX

ps: happy easter :)

Monday, April 09, 2007 2:45:25 AM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, April 05, 2007
So all the design docs have been done, some more vague than others, but they're done and sent for sign off...

The client has come back with quite a hefty amount of feedback already which is going to alter how we go about developing the project, and has expended the scope of it quite a bit, which we're going to have to factor in ( Both budget and time scale wise ).

To touch on the project itself, it's a collection of mini-games which follow you as you go through life, from toddler to retirement age.

And that's about it for now. Hoping to get final sign off on the concepts soon so we can start the actual coding.

( Yeah its a boring blog entry, but projects aren't all flv clips and moving sprites, but hey whilst you're along for the ride you're going to have to take the rough with the smooth along with us ).

Squize.

Wednesday, April 04, 2007 10:53:25 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Sunday, April 01, 2007
Hopefully going to go back to what the stimunation blog used to be, and focus on the actual development of a game from start to end.

It's always tricky 'cause everything has a NDA these days, so it's often a period of 4 weeks or so when you can write very little about what you're actually working on, and then ta dah, here's the game everyone, let us know what you think ( And retroactively answering questions about its development ).

With this project there is still going to have to be a slight viel of secrecy, but I'm hoping we can still give you some ins and outs of it's development along the way.

So I guess we can call this day 1. And day 1 is... writing up the design docs day. Not the most fun thing in the world, and to be honest I'm a firm believer in games evolving rather than being planned out to the nth degree, but this is a game made up of lots ( Around 12 ) of sub-games and a five week turnaround so we really need that structure in place.

This project is a first for me too, in that I'm more project manager than coder ( Due to prior commitments rather than a huge desire to wear that hat ), so more of my time is going to be spent making sure our client is happy, ensuring that olli and Elliot ( Our artist on this project ) know what's going down and when and other such organisational feats.

I think that's about it for this post. I've still got 11 docs to write today which should keep me off the streets, and hopefully they'll be signed off without too much alteration so olli can start getting down and dirty with the code as soon as possible.

More soon...

Squize.

Sunday, April 01, 2007 10:58:15 AM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Tuesday, March 27, 2007
Finally I started working on a new "private" game, basically it should have been an action game ...
... but somehow the idea has been altered and now it seems like it's becoming a puzzler.

For the last couple of days (weeks to be true) since my last post, I've been working on the title screen, mainly to get into the right mood for the style of the game. It also helps a lot to find the overall visual style.

As you might expect I'm not going to reveal anything about the actual gameplay, but it involves a bit of magic, wizards, a wizard's hat, an awfull amount of eyecandy and hopefully as much fun to play as I'll have doing (and selling) it :) ...

Enough words for now, here are 3 tiny parts of the intro animation (or part of the title/menu screen), and the reason for the nice and friendly number of polygons mentioned above:
       

Once I've finished this shot, I'll post the complete image, but there are some details left I want to alter to really make it look the way I want it to.

nGFX

Tuesday, March 27, 2007 4:43:20 PM (W. Europe Daylight Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  |  Trackback