24. December 2008 11:15 by nGFX
Merry Christmas everyone!

At this time of year we'd just like to thank you, all our beautiful constant readers and our sexy newer visitors, for helping make this blog what it is. Without you we'd just be talking to ourselves, and I'm no doctor, but that's got to be a bit mental hasn't it ?

So thanks a lot for keeping us sane, it means a lot to us.

Turkey, tv, unwanted gifts, eating until your eyes bleed, visiting relatives when you just want to play on the xbox, something about the little baby Jesus, a big fat man breaking into your house in the middle of the night, paranoia that you can smell burning every time you turn the tree lights on, getting a card from someone at the 11th hour when there's just no way you can get one back to them on time, wrapping presents far too late and making a really bad job of it, having to spend Christmas with relatives and their weird not the way your family does it rules ( "We don't open the presents til after lunch" ), it's just all good isn't it.

Have a great one,

Squize & nGFX
x

(ps. edited by nGFX):
So Squize was done with posting a good deal earlier than me, so instead of having a second post I decided to add to this one...

If you're not quite so much into Christmas (like me, although, only the stress before it spoils it for me as early as November) here's my usual:

Happy Hogswatchday!

"ER...HO. HO. HO."
-- Death makes a career move (Terry Pratchett, Hogfather)

Tags:

General

15. December 2008 22:02 by nGFX
So I guess a month or so has passed without a word from me, which either means I haven't got something to say or lost interest or something else.

Well, a bit of everything. This year has been a real let down in terms of games, Squize outnumbered me in terms of finished games by far, so what have I done at all?

First the official conversion I've been doing for gimme 5 still isn't really gold (still waiting for the level swapping stuff), which was or still is quite a letdown and has killed a good deal of the motivation I had put into a game of my own otherwise.

Then there were quite a lot flash based applications (not the stuff to write about here) and some .NET based backend stuff.

Oh and I've been doing a heavy "quick fix" session for Ubisoft (yes, that Ubisoft), which ment 3 weeks of 16h days to fix 3 flash games and write a menu in 3 languages (regular readers might find my post related to this) ... I still have to rewrite the third one, but that's another story.
We haven't been involved in the design, but it was quite a lesson for me to make them work at all (read: I got some half fininshed games and a very tight deadline).
If you're eager to take a look ... do it here: Handigo The Game - Ubisoft (first one on the right).

After all that I decided to have a quite long holiday now and start on a game that has been floating around my mind in varoius designs for quite a while now (I did mention that "unfinished" games like my CC port are big motivation killers?).

I doubt I'll do daily updates like Squize, so for now you just get the name (and static screenie of the menu):
ce_promo_menu.jpg

(Oh, and did you notice the "Medals"? While writing on Calisto Eclipse I'm setting up something nice for us all ... more to come later :) )

Back to coding now (finally), nGFX



Tags:

General

4. November 2008 15:33 by nGFX

So what's wrong with this code:

if (this._iDrawLayer & ChipsGame.VIEW_LAYER_A == ChipsGame.VIEW_LAYER_A) {
// draw contents of layer A ...
}

nothing, really. Nonetheless it's not working in CS3 (yet again, prove me wrong).

Basically it's just the unoptimized check if a certain bit is set or not. Let's do some traces:

trace ("with ():", ((this._iDrawLayer & ChipsGame.VIEW_LAYER_A) == ChipsGame.VIEW_LAYER_A))
trace ("without ():", (this._iDrawLayer & ChipsGame.VIEW_LAYER_A == ChipsGame.VIEW_LAYER_A))
trace ("values :", this._iDrawLayer & ChipsGame.VIEW_LAYER_A , ChipsGame.VIEW_LAYER_A)

The result is this:

with (): true
without (): 1
values: 1 1

Interesting, isn't it?
It seems like the compiler chains the & and the == for some reason that escapes me...

So if you get something undesiered with bitwise operators ... use ( and ) around it.

nGFX

29. October 2008 17:46 by nGFX

Back again!

After a good deal of time I finally have something to post about - or let's face it moan about.

As the headling slightly might suggest I'm dealing with sound today.
I think that sound handling in AS3 is a nightmare compared to the ease of it in AS1/2 and I'm not the only one asking WTF?

So in order to play your sound you have to instanciate it, if it's exported CS3 kindly creates a class for you so you can easily use it ... (loading it from an external source is another story)

This is what the CS3 help gives us for embeded sounds ("working with embeded sounds"):

var drum:DrumSound = new DrumSound();
var channel:SoundChannel = drum.play();

My first question was: what do I need the SoundChannel for if I just want to play the sound?

Well, the rocket scientists at Adobe thought that it would be a good idea to add a play() command to the Sound, but not a stop(), so in order to stop our sound playing we *need* the SoundChannel - so we better store it for later use.

Anyway, to make my life easier I converted my SoundUtil class from AS2, basically it deals with the sounds so I don't have to think about it, it has a few usefull commands like playSFX (plays a sound effect, once), playMusic (which allows fading), crossfade ...
I usually used attached sounds (or from an external swf, but the SoundUtil dealt with it ...)
So in order to play music for the menu I'd just do:

SoundUtil.getInstance().playMusic("musicName", 2); // 2 would do a 2 sec. fade in

The AS3 version should work the same, although it uses static functions which then call the singleton's method.

Oh wait. We need to have a class to start the embeded sound ...

To get over that I wrote the add method, which basically takes the name of the sound (or the classname) and then does it's magic.

        public function add (strSound:String, bIsMusic:Boolean):void {
            
            var refClass:Class = getDefinitionByName(strSound) as Class;
            var sndTmp:Sound = new refClass();
                        
            var iTmp:int = this._aSound.length;
            
            this._aSound.push(sndTmp);
            this._objSound[strSound] = { id:iTmp, bIsMusic: bIsMusic };
            
            if (bIsMusic) {
                this._objSound[strSound].spDummy = new Sprite();
            }
            
        }

Ha! that was easy ...

As you see the sounds name gets stored in an object (I just use it as dictionairy), I store an Object with some more values along with the name. And you surely might ask WHY on earth I did create a Sprite for music files ...
Well I'm a lamer, I use the Sprite to attach an onEnterFrameTo it for things like fading :)

Fast forward ...

k. Let's say we play some music, and only wont it to play 2 times, after that the sound should be removed from memory. Luckily we have the onSoundComplete Event, it should return (CS3 help): "The Sound object on which a sound has finished playing."

For me it reads like it returns the Sound that is playing. FAIL!

It does however return a SoundChannel, which of course HAS no information (prove me wrong) about the Sound it belongs to ...
So how can I unload/cleanup a Sound when an onSoundComplete occurs, if I don't know which Sound is playing (and don't want to write a seperate Listner for each sound)?

Oh lucky me...

Thank fuck I store a lot of things in my information object (not only what is shown in the add method), for instance I store the SoundChannel I got from Sound's play() command and I store if a Sound is playing ...

After a few hours of using our favorite search engine I came up with something so stupid it might even be brilliant ...

private function onSoundComplete (e:Event):void {
            
      var strKey:String;
            
      for (strKey in this._objSound) {
           if (this._objSound[strKey].bIsMusic) {
               if (this._objSound[strKey].chChannel == e.target) {
                   this._objSound[strKey].chChannel.removeEventListener(Event.SOUND_COMPLETE, this.onSoundComplete);
                   this._objSound[strKey].bIsPlaying = false;
                   // do some cleanup
               }
           }
       }
            
}

Basically I loop over all music "files" that are playing and *compare* their SoundChannel with the one returned by the Event.
That's so insanely stupid! But it works. Sweet.

Maybe it helps some of you ...

nGFX

9. October 2008 19:52 by nGFX
Just some news about the FHM game awards.

Teague at the sickeningly talented Hyperlaunch sent us a mail mentioning that they're working on this years awards, and that the awards were about recognising great development and developers, celebrating their efforts and thanking them for allowing so many of us to waste our time playing games when we should be working.
He also mentioned that everyone who entered would be given some cheeky widgets to help promote their games, plus a badge to stick in your game ( "FHM Web Game Awards '09" no less ). The outcome will be decided by user voting and the winner will recieve £3000 ( Or if you're in the land of dollars, enough to buy a house ).

You also have the choice to make a brand spanking and hopefully £3k winning game, or submit one of your existing ones and try and win without any real effort.

But you know what ? We value our integrity here, and we won't just pimp any old thing just 'cause someone wrote us a nice email.

Bollocks.

Well now the genie is out of the bottle click [ here ] to find out more. It's well worth a bash, and although I don't know if we'll have anything new to offer up I'm sure we can wipe down some of the old stuff, spray it with some deoderant and just pretend it's new.

Squize.

PS. Remember the kick back to us if you win. It's only right and fair.

Tags:

News

8. October 2008 11:14 by nGFX

What do the following things have in comon?

 

test.swf (5,87 KB)

goAway.swf (8,07 KB)

test.png

goAway.jpg


After my funny little episode with the hacked version of Law of the West I started wondering how to prevent that little pricks that can use an URL changer or decompiler to mess around with my stuff. Above you see what might be a solution. It will not stop someone who really, really wants to see your code from seeing it in the end but it will make it reasonably hard.

So how can you prevent that someone just grabs a decompiler, changes things and publish it back?

Maybe if there is no game inside the swf, at least not directly visible.

This is a screenshot of the library of the goAway.swf. Nice, eh?

Right now goAway is a neat little console app (so you can batch it), that takes an swf, optional a textfile full of vars (so you can check them later from the game itself) and spits out a png.

This can be included in another swf (to be released) and is unpacked after loading - and viola you have your swf again, though it'll be like a loaded swf, so you loose your "root".

There is a lot more security related portential behind this:
- load the png from a server instead of including it.
- use a key to decrypt the png
- create the png on the fly on the server each time with a new key
- store multiple swfs/files in a single png to pack a multi file game into a single distributable swf without a lot of trouble
- and and and

The above swf is just a proof of concept and there is still alot to do on the goAway app in oder to make it useable (maybe a frontend, new features (like dynamic png dimensions, splitting into multiple png files for more security, different ways of reading writing the data into the png (byte order)) not to mention an AS3 class to easily handle the goAway png.

After all I'm quite pleased with the idea, as it makes it quite hard for script kids to mess around with a published flash file with the available tools. Making hacking a game just that little bit harder that is needed to seperate the users from the coders.

And of course SiCo will be used to obfuscate the goAway code ...

Ha!

nGFX

7. September 2008 14:25 by nGFX

I've been silent the last couple of weeks, too silent I reckon, but ... yet again I've been oompha-loompha'ing for various projects.

One of this projects really raised the bar in several ways (I think I'll do a rundown afterward - deadline is tomorrow, really, no way of extending it, even for a few minutes).

So for now let us assume we're dealing with a purely hypothetic project (as this is not about what all went wrong during the assignment).

This fantasy project should contain this:
- a menu, 3 languages, able to load in various games
- multi language support for the games (which have been done by someone else)

As I'm used to work with Flash's strings panel it was a logical choice to use, basically you can set it to "auto" mode and all assigned Textfields will be replaced at runtime with the associated one, you can also set a new language while running and everything is fine.

Or so I thought.

The menu worked fine, but then I got the first game ... oh, now we Imagine the first game ...
Some files ...
- one 150MB fla, called "library" - LIBRARY? yes.
- one 90MB called "game" ...
- a few more files (levels), each around 90MB

OK, library mustn't mean something bad.

Or so I thought.

Library in this case means something bad. BAD. BAD. BAD.
It meant: shared library (for those of you lucky enough to have not heard about it yet ... read about here.)
Oh when you're back from reading about it, you surely think "oh, that is nice"

WAIT! Don't ever even think about thinking "oh, that is nice" when it comes to shared libraries. They are EVIL!
It's the foot and mouth disease of Flash's features.

(imagine using one)
You'll first notice that you lose control about preloading - shared libs work like things exported to the first frame BUT without being able to detect their size.

Fast forward now ...

So you have the menu using Flash's strings panel, working, now it's time to load in the first game ...
I chose to use the good old and trusty loadMovie method instead of the MovieclipLoader class. So it was just a simple load and detect the size, start when done.

OR SO I THOUGHT.

Well, I knew from other project that when loading an swf that uses Locale, the newly loaded swf (using Locale, too) replaces the language data from the holder swf. This is OK and it makes sense if you think about the fact that a static class is assigned to _global in AS2. So the game used the same language files the menu does ... easy.

The dirty details ...

The game loads in a couple of external mp3 files, so I had to take care of that, too - easy enough, so no problem there too..
This is what we see:
- loading starts, use getBytesLoaded / getBytesTotal to see when it's done ...
- tracing shows 140k of swf to load, fair enough.
- after loading that, nothing happened. For 900k nothing happened - Flash was loading in the shared lib.
- then I was able to watch the mp3 files loading and afterward start the game - finally.

The problem is that the user might think that the game isn't loading at all when the shared lib is loaded - THERE IS NO WAY OF WATCHING IT LOADING!!!!!!
First I thought I could trick my way out of it by loading the shared lib FIRST and then hope the cache would kick in when the game is later loaded - nice try buddy. No, it doesn't work (at least not very well).

I ended up by using a faked (and then real) file list to load the game, basically it shows that there are 2 files to load.
First the swf is loaded, then while waiting for it to load the shared lib, I fake a progress and later I add the mp3 files to that list also to watch them loading, too.

Now that this is off the list ...

Yehaa the game is loaded and ready to to be played ...
- level one works ...
- the "level done" screen pops up AND ... it is definitely NOT in the language I've been using in the menu. WTF?

In fact the game was now all in German, whereas I selected English for the menu.

WHY? What happened. I had no idea.

A lengthy search using your fav. search engine did not give us anything.

OK, so we're on our own again (hey, after all this is Flash).

Let the tracing begin ...

First thing I checked was the language set using Locale.getDefault():
- startup: "de" (because of my desktop language)
- set it to "en"
- (checking, yes now everything is "en")
- load game: still "en"
- play game: still "en"
- show level done: still ... "en"

BUT IT FUCKING SHOWS ALL FUCKING STRINGS IN FUCKING GERMAN!

More fast forward ...

A few hours later I have lost a good deal of hair, brain and energy and of course all the trouble is caused by ...  right . the shared library.
It seems like it overwrites the language data with it's own values but doesn't report it to Locale (so you can see it).

And they lived happily ever after ...

I ended up, oh, we "would" (we still imagine the project you know) with loading the game, loading all external files and THEN reload the language file.

nGFX

ps: next time I tell you about the joys of using art based levels that consist of over 900 vector based drawings, movieclips and components ... which take almost 10 minutes to copy and move ... joy.

4. August 2008 07:28 by nGFX
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

24. July 2008 08:37 by nGFX
FINALLY!

CC is going to become early alpha tonight. I spent the last week adding levels and testing them along the way (which takes some time because they are quite ... complex ... and not easy to play). While making sure the game behaves like it should and fixing things that don't work quite like expected.

There are still some features missing and *a lot* of love left to add, but I think the engine is pretty solid now, it runs smooth in the editor and because it's tilesize independent it should also run in game mode (I'll see that later today).

Marmotte from dot-invasion has dome some georgeous tiles so this is done, too.

Basically there are a few renderings left (mainly for the player deaths) and I have to do all the sounds (including a lot of speach) and music.

And for the sake of it:
cc_promo_00.jpg
Our hero ...

nGFX

Tags:

General | News

9. July 2008 10:03 by nGFX
I think it's time to question my motivation.

While working on client projects, I allow myself always a more or less big "sideproject" (because as Bill Murray put it in Groundhog Day: "Keep the talent happy.").

I usually try to stay on the easier side (game wise), but I'm not the button basher game type of developer, although I tried it ...
When sitting there and plotting down ideas, the transform from "one week and done" to "woha that's big" is almost instant.

So let's just accept the facts.
Looking through my sketches it shows that this is again no quick and easy project, I see a lot of locations, all done in 3d, different maps, a story that ties it all together and of course weeks of work.
I think that anyone with some gamecoding background (i.e. coding games beyond the scope of flash) is looking for: the big one. A real game.

Puzzle games are somewhat of a different league beside all the clicketyclick-crap that is called "game" and not many flash games reach into that region for me.

One of the few ones I admire for it's depth is Luxregina's Two Kingdoms.

But how can you compare a flash game to a "real" game?
Savegames? Maybe.
Levels? Maybe.
Story? Maybe.
Depth? Certainly.

What was I talking about?
One of the questions that keep bothering me for the last days is: does it pay out?

Beside the fact that it will be quite fun to do a big game, this one question is really nagging me (espeacially since the LotW hacking incident).

There's the fact that flash isn't save at all. each damn script kiddy ot there could grab this application (which name I won't tell) and just open your swf and change a lot of things without even having to dig through the code. Changing an image or adding a new button is a case of a few mouseclicks. AS3 seems to make it a bit harder, but I doubt that it will be forever. (Maybe there might be some sort of solution, Squize and I have been talking about a ugly way of protecting you game from just changing things on the fly, but we need to test that before I can tell you more)

Using Director isn't an option at all and one of the environments that really would make me go away for coding a game isn't yet reachable because the dev environment is on Mac only and I don't have the space to have another box standing around, here even if is a pretty one.

Because we all know that such a project is normally for pleasure only, you still have to ask if you can get the odd quid out of it - can you?

Sponsoring isn't a route, because as I see it it's not a win situation for the developer, the exposure gained doesn't reflect in website traffic at all. The money isn't nowhere near what can be charged for a client development or an exclusive deal, but it's unlikely that you get one.

Ingame ads seems to be an option but you need some fairly good exposure to reach numbers that pay out well, too.

It's all personal again ...
So it all sums up to: do you enjoy doing such a big game. Well I certainly would. But there are doubts.

K. let's get back to some coding of CC, and later this week some tests on security ...

nGFX






Tags:

General

GYW on the web ...

Even more of GYW ...
GYW Homepage +GYW GYW on Facebook GYW on Twitter nGFX on Twitter

Month List