Sunday, November 14, 2010

Language features...

So at what point do language features become a hindrance? Well having learnt using BASIC, I know what the features of other languages has allowed me to do. SO lets have a little lookie and see what these features have added.

First up: TYPES.

I remember coding on a ZX Spectrum and being incredibly jealous of the BBC as they had INTEGER variable types. This option allowed your code to run MUCH faster than using the standard floating point number variable. Now, back then ALL floating point code was done through emulation and so was much, much slower. Nowadays, doubles (which is what Game Maker uses) is all done in hardware, so why do we care? Well first, it's not always done in hardware, so we're back to the CPU doing emulation and that's really bad. In fact, even is we're doing this on a machine with hardware for doubles, integer computation is simply faster, what with the multiple execution pipes and single cycle execution on most hardware, if you can do it in integers, you should at least have the option. After all, how many FOR loops really need floating point? Lastly... How much would this really affect folk who don't care? I'd argue not much. For example...
   i = 1.12;
b = 12;

compare that to something like...
   INT  b;

i = 1.12;
b = 12;

I'd say if you don't want to use them, it's not exactly going to bother you, but if you want to declare the variable (with INT, DIM, VAR or whatever we end up using), then you will not only get a speed boost, but it'll help you debug your code because you KNOW it can't be a fraction! That can be a valuable bit of info.
Second: STRUCTS

I'm wondering how I can even begin to say how important this is. Lets give a couple of examples. (this isn't proper code, so don't jump on errors please!)
    BaddieID[i] = id
BaddieGridX[i] = round( id.x/16);
BaddieGridY[i] = round( id.y/16);
BaddieType[i] = enemytype;
BaddieParent[i] = id.parent;

Now, in this little sample, we need multiple arrays to deal with storing all the bits of information I need for processing later. This is pretty common when coding and having multiple, dynamically resizing arrays is a nasty thing. So what can we do to improve this? Welcome to the world of structures.
   struct SBaddie{
id,
gridx,
gridy,
type
parent
};

baddie.id = id
baddie.x = round( id.x/16);
baddie.y = round( id.y/16);
baddie.type = enemytype
baddie.parent = parent;

Baddies[i] = baddie;

(I'm deliberately avoiding adding any types here... but you can do)
Now... how I'd hook all this up is unclear, but having a single object (much like a standard, but very lightweight Game Maker object) with variables you can access can mean you can contain data in a single packet. This means you no longer have lots of dynamically resizing arrays (which is always a good thing), but if we are to expand what can be passed into functions, it also allows you to pass a lot of data in a single blob, removing lots of parameter stacking. This is all good, not only from a performance standpoint, but simplifies your think about about variables you're dealing with. No longer are you thinking about lots of individual variables, remembering which ones do what, you now have a single variable with all the information you need and this again simplifies your work.

Structures are good. Structures are VERY good.


Third: FUNCTIONS.

Being able to breakup large functions into smaller common parts is nice, not just from a readability standpoint, but for allowing you to reuse code better. It's a very good skill to learn; making code general so you can use the same function over and over again. This not only teaches coding flexibility, but allows you to start to make an API for certain features. Good APIs are a real skill, and one thats vital to learn if you ever want to progress as a coder. All that said, if you don't really care about coding and it's simply a means to an end, then being able to break your functions up does make code just simpler. Having a function that is pages and pages long is horrible to maintain, and will introduce bugs, so this would also help you reduce bugs as each function is smaller, and easer to think about. So again, its another good one.

Fourth: CONSTANTS

Simple one. PROPER constants. This is mainly an internal thing... but allowing you to define them in code would be great.


Now... I'd also say there are features that would just confuse most folk so we should just avoid them. Things like anonymous delegates, the C++ << style operator, operator overloading, templates, and even to some extent #defines; these are all simply not required inside GML. While I do like #defines, I think they can be so badly used, I'd simply avoid them.

EDIT: Oh... and the other thing I'd LOVE to add; argument passing to the instance_create(x,y,obj) function. This would be brilliant. This would allow you to do stuff like this...

    w = instance_create( 10, 10, cBullet, "smallbang.wav", false, sSprite );

I could have used this quite a few times already....

No comments:

Post a Comment