Outer Court

Basic - Blitz Basic - Programming Style in Blitz Basic

Good programming style is nothing you can measure, really. More of an art, than a science -- but isn't that true for most aspects of game programming?
Game programming style is nothing the player might notice in the end. It might not even be something you can teach in its whole, but I will give it a try here for some aspects.

With good programming style I mean quality in all the areas you really don't see except when looing at the source code. Programming style covers syntax, patterns used, the structure you break your program into. But why even bother if there's no difference in the actual executed game?
I think there's many reasons to bother:

  1. Readability results in maintainability.
  2. Breaking up structure in small parts increases reusability.
  3. By using different layers of abstraction (one describing what you want, another how you want it to be done exactly), more complex game features are possible.
  4. Elegant program flow through high encapsulation keeps your head free to concentrate on the actual problems ahead.
  5. Certain "bugs" result in unexpected, positive rewards.

Some other important issues however are not directly connected to programming style:

These concepts are not exclusive to games programming, and certainly not exclusive to Blitz Basic. Some things you find to implement easier in a certain language, for other things there are no "native" constructs; but if the language supports some basic features, the lack of certain constructs won't keep you from implementing your own.
A definite lack in the current Blitz Basic language you won't find a workaround however is explicitly declaring variables. It will be a great time saver when debugging if it's ever becoming an option, since you will find misspelled words at compile time.

BASIC flavors (like Blitz Basic, or QBasic), in my opinion, are ideally suited for a good programming style:

Some BASIC flavors don't support OOP, Object Oriented Programming. Natively, that is. Others, like Microsoft Visual Basic 6 (and soon, Visual Basic .Net), include the concept of classes and events.

Readability

Spacing

First, I think practically everybody does it, tabbing or spacing:

Not too good (example without spacing):


for x = 1 to 20
for y = 1 to 20
paintTile tile(x, y), x, y
next
next

For each wrapped scope, like the inside for a for-next loop, there should be one tabbing. If you don't use tabbing, you might use four spaces.

Better (example with spacing):


for x = 1 to 20
    for y = 1 to 20
        paintTile tile(x, y), x, y
    next
next

The structure here is much more obvious.

Explicit names

If you didn't hear of magic numbers, you certainly experienced them. It's those numbers used everywhere within the program where there's no clear explanation to them.
And I don't really mean a comment explaining what the number is. I'm not a big believer in documenting bad source code; why not write it self-explanatory in the first place?
You might even go so far to create temporary variables just to explain a certain calculation and break it up in its seperate parts.

Not too good (example with magic numbers):


for x = 1 to 20
    for y = 1 to 20
        paintTile tile(x, y), x, y
    next
next

Better (example without magic numbers):


for x = tileFirst to tileLast
    for y = tileFirst to tileLast
        paintTile tile(x, y), x, y
    next
next

You might also use a way to test the boundaries of the array you iterate through if you want to make the loop boundaries more obvious.
Some of the big pro's for avoiding magic numbers except instant readability:

Vertical spacing

You can use double returns to more clearly seperate parts of the program. (There are no easy rules I would know for that, like there are in horizontal spacing/ tabbing.)

Avoiding abbreviations

Abbreviations might save time when writing a line of code (depending on the programming enviroment and its auto-completion features, or your capabilities of making use of copy-and-paste shortcuts, it might not). But it might cost a lot of time writing a long program, since readability suffers. Especially for other people reading your program; or yourself, when you dig through older code. What might seem obvious to you might not seem obvious to others; or even your future self.

Not too good (example with abbreviations):


if spX > spLim then
    spX = spMax
endif

Better (example with verbose variables):


if speedX > speedLimit then
    speedX = speedLimit
endif

You might make rare exceptions from the rule of avoiding abbreviations; there are idioms, variable-names every programmer might know, where the verbose version would decrease readability. (Think the "for i" loop.)

Mixed case

Variable names should be written in mixed case if they consist of several sub-words. The first letter of each word which comes in the middle of a variable name should be written in upper-case.
If you follow the rule to write constants all uppercase (you might have reasons not to, to allow for easy redefinition of the variable later on), you can use underscores inbetween words.

Sometimes, mixing case might hint that using types might be even better. So speedx might become speedX, which might later become speed\x.

In general, build-in commands of the language will be formatted by the programming environment you use. Typing endif might result in EndIf.

Not too good (example with all lowercase):


spritesize = defaultspritesize

Better (example with mixed case):


spriteSize = DEFAULT_SPRITE_SIZE

Breaking up structure

Of course, every good program is split up in sub-functions. They will enhance reusability and also make the program easier to understand. The smaller and more precise a function, the higher the chance you can reuse it, even from within slightly different contexts.

There is no easy rule-of-thumb as to how long a function could be, but if you have to scroll your function to see it completely on a 1024*768 resolution... you might ask yourself if you can find ways to break it up into more functions.
Another good sign of an overlong function is inline commentary within a function explaining exactly what the subparts are meant to do. It's much more elegant and useful to use self-descriptive function names:

Not too good (pseudo-code example with overlong function):


Function doManyThings()
    ;do this
    foo
    bar
    foo
    bar

    ;do that
    foo
    bar
    foo
    bar

    ;do more of this
    foo
    bar
    foo
End Function

Better (pseudo-code example with small, precise functions):


Function doManyThings()
    doThis
    doThat
    doMoreOfThis
End Function

Function doThis()
    foo
    bar
    foo
    bar
End Function

Function doThat()
    foo
    bar
    foo
    bar
End Function

Function doMoreOfThis()
    foo
    bar
    foo
End Function

Note that the variables used in the three different parts have a shared variable scope in the first, bad example, and a seperated variable scope in the second, better example. Seperating variable scope clearly will prevent errors like wrong initial values of variables, or having to use alternative variable names.

To see another bonus of this approach, imagine you would need to use "do this" again:

 
Find more at www.blitzcoder.com

Basic
Goodies
Design
Tech
Email
Make a donation