• 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.

[JASS] Question on nullifying variables

Status
Not open for further replies.
Level 13
Joined
May 24, 2005
Messages
609
Hey there,

let's say I've got a function like this:

Code:
function GetUnit takes nothing returns unit
    local unit u
    set u = ... whatever
    return u
   //  set unit = null
endfunction

Usually, I'd nullify a unit variable. However, in this case I can't because it needs to be returned. So I cannot use 'set unit = null' at the bottom.
In summaray, I'm afraid this might leak, because u isn't nullified.
Anyone knows what's right here? Should I use a global variable instead?

Thanks
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
mckill2009, learn to program... I have never ever seen a language whic runs code after a function call, especially since return restores the processor to its state before it made a function call so I see it as impossible for it to run any code beyond one.

MoCo, yes that does leak.
There are 2 appraoches you can use.

1. The hacky approach
JASS:
function GetUnit takes unit u returns unit
    set u = ... whatever
    return u
endfunction

Function arguments act exactly like locals except they do not leak (they decrement reference counter on return). The disadvantage is you need to pass an argument on call but that argument can be null if you are just using them as a local. They may or may not be slower than locals as well.

The other approach is the direct approach.
JASS:
function GetUnit takes nothing returns unit
    return ... whatever
endfunction

You can just return the element skipping a local and thus this problem.

Functions that are atomic and blocking (so only 1 chain of execution is running them at a time) can skip local storage and instead use a dedicated global storage index avoiding this problem completly.

JASS:
globals
    unit u
endglobals

function GetUnit takes nothing returns unit
    set u = ... whatever
    return u
endfunction

There will be a temporary handle index leak between function calls due to u still retaining the value. This however is only a problem if the function is not called regually and is a once off leak (it will atmost leak 1 index and that is after the final call to the function. For improved efficiency it is recommended to reuse the global variable in as many functions as possible as this both reduces the effect of the temporary leak (as the value is regually changed) but also keeps resouce usage down (1 heavilly used variable is more efficient than dozens of seldomly used variables).
 
ok my mistake on post #3 about the "return u" but functions like that is useless
anyway if it's not used multiple times like a library, do it in the calling function or directly...

also, not nulling leaks just a little and it's not a must to do it, the reason for this
is I've tested to create 3000 units with & without nulling them but the gap of
RAM usage is really not big, just below 60bytes...
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
also, not nulling leaks just a little and it's not a must to do it, the reason for this
is I've tested to create 3000 units with & without nulling them but the gap of
RAM usage is really not big, just below 60bytes...

It is not about RAM usage... It is about the finite number of handle indicies the game has and that there is some performance penalty for exessive numbers of them.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
if you're talking about lag, well, both methods lag even if 1000 units created...
1000 units should not lag with eithor method seeing how neithor should be generating any net traffic.

There is however a performance penatly to certain opperations when large numbers of handles leak. 1000 is far too smaller a number to see any difference but at 100000 handle indexes leaked creating 1000 units might take noticably longer (if the opperation is effected by handle index leaks). This is the same reason why not freeing objects causes performance degredation in WC3 since memory leaks alone do not make opperations take longer. This means that WC3 uses some opperations which related to O(f(n)) where f(n) increases in some way with n and n is the number of handles or handle indexes used.
 
One factor is the number of objects that need to be rendered.
Warcraft III uses more operations for objects that you can see than objects that are on the map.
Rendering is done for objects even if you can't see them.
This is shown because a unit outside the map bounds only freezes and crashes the game when
the next frame is rendered. It doesn't happen because his coordinates are out of bounds, it's a
graphics problem. The unit isn't in your view and yet he still had to be rendered.
Blizzard seriously needs to optimize Warcraft III and whoever wrote the Jass Virtual Machine
needs to rewrite it completely.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
One factor is the number of objects that need to be rendered.
Warcraft III uses more operations for objects that you can see than objects that are on the map.
Rendering is done for objects even if you can't see them.
This is shown because a unit outside the map bounds only freezes and crashes the game when
the next frame is rendered. It doesn't happen because his coordinates are out of bounds, it's a
graphics problem. The unit isn't in your view and yet he still had to be rendered.

This is not entirly true. The game does not render animations for context that is offscreen. This can be seen by pannind your camera over buff effects that are persistent and made at the same time so they appear out of sync (as it plays the animation only when near the screen view). If it really did render context for every object on the map the game would be unplayable so it only renders context for objects near your viewport.

This is shown because a unit outside the map bounds only freezes and crashes the game when
the next frame is rendered. It doesn't happen because his coordinates are out of bounds, it's a
graphics problem. The unit isn't in your view and yet he still had to be rendered.
Do remember the game engine also opperates in frames. For efficiency these are loosly tied to the game frame rate (as it would be stupid rendering more frames per second than the engine makes changes). It could simply be the fault takes 1 game frame to occur.

If you can prove it happens during and as a result of the frame render process, then it will probably be caused by the "bottem-less pit" problem that 3D graphics have. To detect which context is near the view port it might have to resolve unit height. Unit height is based on terrain height + flying height. The edge of the map has no terrain height (as its the edge of the world). Can the algorthim for terrain height resolve points off the map edge? I think you can see why this could be the cause of the crash.

This is a very common cause of crashes in games. Lego StarWars Clone Wars had one such crash where in 2 player mode a combat machine would fall though the ground at the start of the mission (you could see it dissapearing) and the game would then eventually crash unless you exist the mission quicky and choose a different machine.
 
then it will probably be caused by the "bottem-less pit" problem that 3D graphics have

Wow, you indeed learn something new everyday.
But for some reason, Warcraft III only crashes if the unit exits the map bounds from a certain side (And this side is different for every session)
Well, at least that's what Vexorian's tests have shown in the past. They probably changed this in the newest patch :p
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
If i remember correctly, putting an unit outside the whole map (GetWorldBounds) is safe if ...
you do nothing :p
Including, but not limited, to camera movements and ordering the units.

I just mean that putting the unit outside the map doesn't crash wc3 by itself.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
The crash occurs only if it fails to displace the unit back onto the map. This is especially prone with high displacement off the edge of the map.

There also used to be a crash where a unit failed to be displaced inside the map bounds. You would notice a unit walking into a cliff or some other unusal position and the game would crash (especially if you were viewing the area). Have not encountered this in ages though so I suspect it was patched in some form.
 
Status
Not open for further replies.
Top