• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.
  • It's time for the first HD Modeling Contest of 2025. Join the theme discussion for Hive's HD Modeling Contest #7! Click here to post your idea!

Creating globals instead of locals?

Status
Not open for further replies.
Level 15
Joined
Nov 30, 2007
Messages
1,202
Do you usually create genral purpose variables, for example yesterday I needed a group iterator and it uses two temporary unit groups to store the units, now I need to use such a thing again. Do I reuse those variables?

How far do you take this, you create udg_u1 instead of local units?

What advantage does a local variable really have?
 
Last edited:
Usually I'll create globals when I need them. General purpose variables are fine, e.g. "TempGroup" or "TempUnit", but you have to be careful whenever you use them--they can be overwritten, even when you don't expect it. e.g. let's say you have some script that does this:
JASS:
set TempUnit = someFootman
call UnitDamageTarget(TempUnit, ...)
call BJDebugMsg(GetUnitName(TempUnit))
Let's say you have a trigger with a damage response event, and that trigger overwrites TempUnit. Then that means TempUnit will change after UnitDamageTarget() (unless you use a temp local and reassign it after you finish using the variable). These kinds of occurrences are unpredictable and incredibly hard to debug without a lot of foresight. So it is usually just better to use a specific global for each library/scope.

As for locals, I recommend using them whenever you need a variable only within a particular function. It is just good practice. You don't want to create globals too unnecessarily since that crowds the global scope and can cause slower lookups (at least according to nestharus). It won't be a significant difference though--so it is mostly just preference. But it is much easier to read a system when they differentiate between the two.
 
Yeah, basicly it's good practice to have autonomous code with locals, so functions can run alone.
Code is also cleaner and sometimes easier to understand if everything is declared/removed
within the scope of a function itself. (as PnF also said)

But in JASS for example, there is this group case.
You usually only need 1 group for enumerations.
So one could say it would be silly if you create/destroy groups frequently,
if you could use one global group instead which is only created once and never destroyed.
Also for configuration things it's usually better to have globals, as you can just seperate them from code.

Only for speed I would not use globals over locals.
Sometimes it makes sense to use globals and sometimes you need them.
But the general approach if you make a function is working with locals I would say. :)
 
If you're using GroupUtils, there is a global temp group for this purpouse, named ENUM_GROUP i think. I use it for all my enumerations where i don't need to save the group afterwards. It's OK to have general temp variables like this, as long as you make sure there are no conflicts. You might want to place all shared variables and functions in its own "common" library though, in order not to screw up library dependencies.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
If you need to call a GroupEnum inside a GroupEnum filter or if you have to deal with recursice stuff (with events triggered for example), instead of a global variable you could use a custom function which will handle an array of groups for you.

EDIT : Ok, just read GroupUtils on wc3c.net and such functions already exist with all safety checks if you want.

Like that :

JASS:
library Groups

    globals
        private group array Group
        private integer N = 0
    endglobals

    function GetGroup takes nothing returns group
        local group g
        if N <= 0 then
            set g = CreateGroup()
        else
           set g = Group[N]
           set N = N-1
        endif
        return g
    endfunction

    function ReleaseGroup takes group g returns nothing
        set N = N+1
        set Group[N] = g
    endfunction


endlibrary
I'm aware that i can make speedfreaks happy with a such GetGroup function :

JASS:
    function GetGroup takes nothing returns group
        if N <= 0 then
            return CreateGroup()
        endif
        set N = N-1
        return Group[N+1]
    endfunction
And even "better", create a bunch of groups and fill the array with an initializer, so no need to create groups when the function GetGroup will be called, but oh well ...
 
Last edited:
There is things such as WorldBounds, altought I don't really get why such a thing needs to exist. But still one could do the same thing for players. Defining them in an array, if they are computer, user, active etc and also include neutral player definition.

Yes, you could. It all depends on how often you access something like that.

But min/max optimizations really don't make a difference in the end. It is better to optimize in places that matter (e.g. timers/big code load). Everything else is just a matter of nanoseconds. That's why there isn't a system to speed up every access.

WorldBounds and the LocationZ scripts are kinda exceptions since they are also more convenient to use than a regular script. But if it is speed that you desire, then it really isn't necessary.
 
Status
Not open for further replies.
Top