Opinion - To Global or not to Global

Previous topic - Next topic

XanthorXIII

Quick question for those that have been doing this longer than I have, but what is your opinion on using Global for declaring variables. Is it ok in some cases and try not to whenever? Is there a danger to me using them aside from the you may change a value somewhere and not know about it?
Just general thoughts, not looking to start a bar brawl.
Owlcat has wise

Slydog

#1
I'd say use them without any guilt when it makes sense, but not when it's not needed!  Clear?   :noggin:  ha

Take 'game_state' for example.
You COULD create a 'GameState()' TYPE that includes functions such as Get() and Set(), but that is overkill, imo.
A simple global variable 'game_state' does everything you need, and it has to be global, so all functions can access it, or set it.

I like using global TYPE instances when it makes sense.  I don't like having global variables like 'player_name', 'score', 'time_remaining', etc when they clearly belong in a 'player' type, or 'level' type.  But, then the TYPE instances are global, so it's just a design preference.  (ie: 'player1.score', 'player1.name')

Never use a global when it's not needed anywhere but a specific function.  Sometimes you could rearrange your code to not need globals in some situations, but that's on a case by case basis.

FYI, I have quite a few globals in my code, even some in my libraries (which I hate, just sometimes it makes things easier), etc.

I sometimes use globals when I should be using constants, but when entering the code I wasn't sure if I needed to modify the value or not.  And, I'm not sure what advantages constants have over globals, except the obvious safety factor.

What I don't like (for no reason, other than being a 'purist') is that globals defined in a separate file (like a library) are global for the entire game.  I would prefer they be only global to the file, then I could reuse those variables in my libraries if I preferred, and keep the code 'hidden' from the rest of the game.

[Edit] May I add that using globals for game programming might have different advantages/reasons than 'traditional' programming.  Speed for instance.  It's much quicker to access a global variable than a complicated, but 'proper', class structure (ie TYPES).
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

quangdx

My two pennies on the matter,
my programming background was on the Gameboy, coding in C and ASM for the speedy bits.
If I understand it correctly, purely from a speed point of view, I only use GLOBAL variables.
My reasoning is that in theory it takes longer to create a new variable each time a function is called,
rather than set an existing variable.
I have default variables for loop and condition handling labelled, i,j,k,n,m,x,y,z
and then whatever variables the game requires.
It may not produce the cleanest/neatest code, but when coding on a limited system, speed is the most important part.

This is probably why I could never get to grips with JAVA and Objective C,
the need to declare everything always annoyed me.

Although I may have gotten this all completely wrong all these years and there is no speed difference in using GLOBAL and LOCAL variables.
Asobi tech - the science of play.
Spare time indiegame developer.

XanthorXIII

Shouldn't the compiler already know what the declared variables from program are? Then it's just a matter of it copying to those values when they are needed?
Owlcat has wise

Qube

I find I tend to use a lot of global variables in games. My main train of thought on this is that if I need a variable to be used across a lot functions then it's much neater to use globals rather than passing variables over and over again as that would lead to a greater chance of mistakes.

Local variables I tend to use in for-next loops, temp variables for working out stuff or in functions that don't need those variables to be accessed outside of that function.

I also use the option in GLB to alert me if I have undeclared variables which pretty much puts a full stop to incorrect naming of global variables in routines where you scratch your head for days wondering what's wrong only to figure out you had x instead of X :p

Overall though, use what ever suits your coding the best, what ever you find the easiest to get along with. The only rule I do force myself to follow is commenting blocks of code so i can easily follow it when viewed weeks / months later.

Perfectly neat and compliant code to match the nit pickers of this world won't make your game any better :)

XanthorXIII

QuotePerfectly neat and compliant code to match the nit pickers of this world won't make your game any better :)
Good quote there.

I was doing some work last night and doing some reading up on TYPES and Arrays. It's almost silly to have an Array that I have to pass to the function because those are already pass by reference, which is the same as Types.
So really Local and Global doesn't matter in as much, however I think having good comments and functions organized would probably do me more good then to worry about Local vs Global.
Owlcat has wise

quangdx

This is kind of the point I was trying to make,
by using globals you don't have to pass variables around,
which should in theory speed things up.
Asobi tech - the science of play.
Spare time indiegame developer.

XanthorXIII

The big problem though as I was thinking it through was that if you started a new game and had to modify a Global is that you would need to reset the Global back to it's original state if you needed the original value.

For example.
The game has three modes of play. In each mode you start with three lives. If you have just use one variable for Lives as a Global and set it to three, if you don't reset that variable to three when you initialize a mode, you could end up going from one mode to another and find that you have less lives or none at all.
The way I'm starting to think they should be used would be as Constants and that is it. Not even for Types as it would require that you do some clean up for Types. Why not let the function go out of scope and let the object get cleaned up. The way I understand it is that GLBasic has automatic garbage collection and can do this without trouble or memory leaks.
Owlcat has wise

Kitty Hello

There's no garbage collector. Thevery moment a variable goes out of scope, the memory is released.

XanthorXIII

Ok, I thought it did but I guess with no access to pointers we can't really screw up by allocating memory and not freeing it when we are done. I think my point about Globals is still valid but if you can manage them, they really shouldn't cause problems, just a pain if you have to go back and reset the values each time you start a new game, as an example.
Owlcat has wise

XanthorXIII

Speaking of which, if I'm going to pass the reference of the object or Type, would it be possible to pass without using the AS qualifier? Good case for Generics?
Owlcat has wise

Kitty Hello

Uhm. Types and Arrays are always passed by reference.

matchy

#12
Is there a way to not use GLOBAL such as in this example:
Code (glbasic) Select

GLOBAL obj_type[] as type_foo

ok = move_foo(0)

FUNCTION move_foo: temp_index
     INC obj_type[temp_index].x
     RETURN TRUE
ENDFUNCTION



Reset:
Code (glbasic) Select

LOCAL obj_foo as type_foo

obj_foo = move_foo(obj_foo)

FUNCTION move_foo as type_foo: temp_foo as type_foo
     LOCAL new_foo as type_foo

     new_foo.x = temp_foo.x + 1
     RETURN new_foo
ENDFUNCTION



This doesn't make a new type.
Code (glbasic) Select

LOCAL obj_type as foo_type

obj_type = move_foo(obj_type)

FUNCTION move_foo as foo_type: temp_foo as foo_type
    INC temp_foo.x
    RETURN temp_foo
ENDFUNCTION


and is just a replacement to this...?

Code (glbasic) Select

LOCAL obj_type as foo_type, ok

ok = move_foo(obj_type)

FUNCTION move_foo: temp_foo as foo_type
    INC temp_foo.x
    RETURN TRUE
ENDFUNCTION


which is like...(but without the structure)

Code (glbasic) Select

LOCAL obj_x

ok = move_foo(obj_x)

FUNCTION move_foo: BYREF temp_x
    INC temp_x
    RETURN TRUE
ENDFUNCTION


:whistle:

XanthorXIII

Quote from: Kitty Hello on 2011-May-09
Uhm. Types and Arrays are always passed by reference.

Kitty - I got that figured out from the documentation. Let me clarify what I am asking. When passing an object to a function, do we always have to include the AS keyword.

Example

FUNCTION foo: object AS cat
      PRINT "Cat's Age is: object.age,10,10
ENDFUNCTION

Or can I just do the above as


FUNCTION foo: object
      PRINT "Cat's Age is: object.age,10,10
ENDFUNCTION

My goal is to create functions that I can throw into a file and then include that file into any project I make. Then I can pass any object to those functions I need
barring that I know what I can actually pass to that function


Thanks!
Owlcat has wise

Slydog

matchy, I'm not quite sure what you are asking.

But, could your problem be fixed by creating a function in the TYPE such as:

Code (glbasic) Select
TYPE type_foo
  x

  FUNCTION move:
    INC self.x
  ENDFUNCTION
ENDTYPE

GLOBAL obj_foo AS type_foo
obj_foo.move()
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]