my first few examples do beg the question "why not use the global directly" but expand the concept over an entire game code base and you see the logic behind my thinking, I hope lol
I'll try and explain
Quote: "Also, in your last 3 examples you declared Var as global, is there a reason to declare variables as global even though they are always passed into functions?"
I declared Var as global because its being used in the main scope (prior to and within the main game loop), and (according to my own coding preference) this is the only place the global should be used, you can access the global directly in the function yes, but it can simplify array depth by passing a type as ref and access a single element or type of the array, it also helps separate logic from functionality, without a full example its hard to explain but see below and you will get my drift.
Quote: "I was always told to avoid globals as much as I can. This lead to me to creating function that take data by ref, only to call other functions inside that also take the same data by ref, and so on . Is this also considered a bad coding style?"
I think you would be hard pushed to write any program without using at least one global, game states, scores, and a abundance of other information needs to be stored somewhere, right?
so that being said with a well thought out data structure you can minimize global use, or have a whole game running from a single global var.....
Type tEnemyBullet
sprite_id
active
speed
EndType
Type tEnemy
sprite_id
health
bullet as tEnemyBullet[20]
EndType
Type tPlayerBullet
sprite_id
active
speed
EndType
Type tPlayer
sprite_id
health
bullet as tPlayerBullet[20]
EndType
Type tGame
score
lives
state
player as tPlayer
enemy as tEnemy[100]
EndType
Global gGame as tGame
so back to passing by ref using the above as an example, to access an enemy bullet in a function to make the enemy fire you would use "gGame.enemy[x].bullet[y].sprite_id" in the function as the global, but IMO its easier to pass the enemy array as ref from the logic part of your code, it ends up a lot more readable and allows you to access specific parts of your main global without having to retype the gGame.bla every time you access the array, you do not need access to every game variable inside every function so some segregation can really help the logic flow, readability and structure of your code
simple example:
Function Enemy_FireBullet(bullet ref as tEnemyBullet)
bullet.active=1
SetSpritePosition(bullet.sprite_id)
EndFunction
Function Enemy_Fire(enemy ref as tEnemy)
// find inactive bullet
for index=0 to enemy.bullet.length
if enemy.bullet[index].active=0
Enemy_FireBullet(enemy.bullet[index])
endif
next
EndFunction
// logic function, setup timers and such to tell the enemy when to fire
Function ProcessEnemy()
for index=0 to gGame.enemy.length
Enemy_Fire(gGame.enemy[index])
next
EndFunction
as you can see I only access the actual global from the logic, send the enemy type to the main fire function and the bullet type to the bullet fire function, obviously this is a quick air code example and it would need elaborating to make it work but it should highlight my reasoning for preferring to use ref rather than the global directly, and you only need to use ref when you want to change a value of the array or type, if your function only reads values you can pass them normally but if calling a second function that will change the value (as per the above example) then the root function needs the ref keyword.
Hope that makes some sense.