• 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.
  • Create a faction for Warcraft 3 and enter Hive's 19th Techtree Contest: Co-Op Commanders! Click here to enter!
  • Get your art tools and paintbrushes ready and enter Hive's 34th Texturing Contest: Void! Click here to enter!

making a map playable in long sessions

Status
Not open for further replies.
Level 12
Joined
Mar 21, 2008
Messages
375
edit: there's a shitload of leaks in my map so this thread was kinda pointless

not sure if this the right place to post this but wutev

I am making a map that is meant to be played in long sessions (4+ hours). Can I use GUI to achieve this, or am I fucked and need to remake the map from scratch in JASS?

The problem with my map is that wc3's memory usage goes up to 700,000-900,000K in about 2-3 hours of playing it. As far as I know, my triggers are leakless, but I'm still seeing the memory usage go up simply because there are periodic triggers (a projectile system, for example, and other systems) running. I'm thinking that my map is beyond fucked by the fact that I decided to trigger it in GUI in the first place, so I'm considering actually learning JASS if necessary.

Admittedly some of those periodic triggers are not as efficient as they could be, but my hunch is that no matter how much I clean up these triggers the memory usage is still going to go up because GUI is supposedly really shit from what I've read

Anyway, here is the map in question if you want to look at it (old version but yeah). Most of the periodic triggers I'm talking about are in the "Core" folder.
also my triggering is pretty fucking horrendous, please be gentle
 
Last edited:
Level 26
Joined
Aug 18, 2009
Messages
4,099
As far as I know, my triggers are leakless

Well, after having taken a short glance into your map, I can claim they are not. But only when you have plunged yourself into jass/got closer to the internals and know the game flaws, you get an understanding of what's the case anyway. It also allows you an improved handling so you can avoid a lot of new object memory allocation in the first place.
 
Level 12
Joined
Mar 21, 2008
Messages
375
Honestly, you might as well use one of the approved projectile systems in the spells section. There are a ton of great systems in there!

Yeah I guess, I don't like to use other systems though

If I were to use some other projectile system I would like to have a complete understanding of the code; this way, I'd be able to modify the system to suit my needs. Also, other systems tend to contain features that I would probably never use. Maybe I'm just talking out of my ass, but that's just what I think

Well, after having taken a short glance into your map, I can claim they are not.

I guess I'm just an idiot then

Can you tell me where and/or what the leaks are?

If you want 4+ hour sessions, I highly recommend learning the basics of JASS, simply because it's super annoying to code GUI leakless and JASS will allow you to cut the map's code in half (if not less).

I really want to learn JASS, but I have the attention span of a brick. I've read some 'basics of JASS' tutorial and it was more or less me learning stuff that I already know. I just want to learn what exactly makes JASS more efficient than GUI; instead, I seem to have to relearn how to do simple shit like variable declaration before I actually get into the meat of things.

Is there a place that explains the differences in efficiency between JASS/GUI? There probably isn't, but it doesn't hurt to ask, because learning from scratch is a special kind of hell that I do not want to endure :goblin_boom:

Also, there's the case of vJASS. Should I be learning JASS first? When should I even be touching vJASS? I have no idea where to start
 
n00b, let me give it to you straight:

GUI is great, JASS is great, vJass is great.

GUI compiles into JASS. Learn GUI first and use JASS when necessary. JASS requires GUI for things like creating gg_ (game-generated) variables, creating udg_ (user-defined global) variables, selecting special effect/unit types visually rather than having to lookup rawcodes. There are no syntax errors in GUI. GUI is great.

JASS allows you to define functions, local variables, remove most distinction between conditions and actions, have access to the full API Blizzard created, no interface delays as the trigger gets longer, functions can accept parameters and return values. Overall, once you know JASS you can literally personalize your code the way you want it. JASS is great.

vJass is a postprocessor which provides JASS more flexibility - you don't have to use GUI's Variable Editor when working with vJass. Also, you can declare constant variables, private variables and variable types which are otherwise impossible to create in Variable Editor. vJass is great.
 
I really want to learn JASS, but I have the attention span of a brick.
Are you sure mapping is right for you then? No offense, but mapping is a time-consuming process that requires months, if not years of dedication. An "attention span of a brick" (which is a confusing metaphor btw, considering bricks, being immobile objects, naturally have limitless patience) is probably the worst thing you can have as a mapper.

I've read some 'basics of JASS' tutorial and it was more or less me learning stuff that I already know. I just want to learn what exactly makes JASS more efficient than GUI; instead, I seem to have to relearn how to do simple shit like variable declaration before I actually get into the meat of things.
All these things you have to relearn about JASS are the things that make JASS more efficient than GUI.

Is there a place that explains the differences in efficiency between JASS/GUI? There probably isn't, but it doesn't hurt to ask, because learning from scratch is a special kind of hell that I do not want to endure :goblin_boom:
Why would efficiency matter anyway? It's about clean, bugfree code. Efficiency is just a beneficial side-effect. You don't learn JASS because it's faster. You learn JASS because it allows you more freedom and generates cleaner and shorter code.

Also, there's the case of vJASS. Should I be learning JASS first? When should I even be touching vJASS? I have no idea where to start
vJass builds on Jass and compiles to Jass. I recommend jumping right into vJass, as it offers a lot of convenient features that vanilla Jass doesn't have, like declaring globals, encapsulation, dependencies, etc..

These things will make the learning process a lot easier, as you don't have to deal with some inconvenient things of vanilla Jass, like having to use GUI variables or name-sensitive initializers.
 
Level 12
Joined
Mar 21, 2008
Messages
375
Are you sure mapping is right for you then? No offense, but mapping is a time-consuming process that requires months, if not years of dedication. An "attention span of a brick" (which is a confusing metaphor btw, considering bricks, being immobile objects, naturally have limitless patience) is probably the worst thing you can have as a mapper.

yep this attention span of mine is terrible
I've been making shitty maps since 2006, and the map I posted in the OP is 2 years in the making
this is hell on earth save me god

Why would efficiency matter anyway? It's about clean, bugfree code. Efficiency is just a beneficial side-effect. You don't learn JASS because it's faster. You learn JASS because it allows you more freedom and generates cleaner and shorter code.

I don't know, I was just assuming being more efficient would be important in a map that is meant to run for 4+ hours. I'm not here to contest you, you're just talking to someone who's clueless :ccool:

n00b, let me give it to you straight:

GUI is great, JASS is great, vJass is great.

GUI compiles into JASS. Learn GUI first and use JASS when necessary. JASS requires GUI for things like creating gg_ (game-generated) variables, creating udg_ (user-defined global) variables, selecting special effect/unit types visually rather than having to lookup rawcodes. There are no syntax errors in GUI. GUI is great.

JASS allows you to define functions, local variables, remove most distinction between conditions and actions, have access to the full API Blizzard created, no interface delays as the trigger gets longer, functions can accept parameters and return values. Overall, once you know JASS you can literally personalize your code the way you want it. JASS is great.

vJass is a postprocessor which provides JASS more flexibility - you don't have to use GUI's Variable Editor when working with vJass. Also, you can declare constant variables, private variables and variable types which are otherwise impossible to create in Variable Editor. vJass is great.

okay so you're basically telling me learning all of these and using them in tandem is the best way to make map ok

also Waterknight says that there are some leaks in my map so I'm just waiting for him to respond
 
Level 26
Joined
Aug 18, 2009
Messages
4,099
Can you tell me where and/or what the leaks are?

All GUI unit group picks because the BJs look like this:

JASS:
function GetUnitsInRangeOfLocMatching takes real radius, location whichLocation, boolexpr filter returns group
    local group g = CreateGroup()
    call GroupEnumUnitsInRangeOfLoc(g, whichLocation, radius, filter)
    call DestroyBoolExpr(filter)
    return g
endfunction

local ref-counted object variable problem: Ref-counted are not fully released until all refs have vanished but local variables in jass are not reset in that aspect when they go out of scope -> reference persists and object can never rest in peace.

Seeing your multiboard cell setting functions, which are very ineffective implemented in GUI btw, afaik the multiboarditems that get allocated and deallocated there are also ref-counted.

In some places you convert a player to a player group, which creates a new object and do not destroy it afterwards.

string table pollution through concatenation: every string ever created is parked in some global data structure (this is not really something you can avoid other than try to reduce the appearance of new strings), accessing the same string over and over is okay

@jass/vJass:

The jass syntax is very simple because it is verbose and hardly has any features. You should first address this and get a grasp of the fundamentals, so you can read and write it on your own and know the restrictions and basics. Then there is the native API with its quirks that needs to be learned gradually like in any language (vocabulary). It's not required that you know any function and type but the common ones and especially the system-relevant stuff. vJass mounts OOP concepts and allows you to write neater and more compact. There are a few other preprocessing languages but vJass still looks jass-y and understands pure jass. You won't need all features of vJass either.
 
Level 12
Joined
Mar 21, 2008
Messages
375
All GUI unit group picks because the BJs look like this:

JASS:
function GetUnitsInRangeOfLocMatching takes real radius, location whichLocation, boolexpr filter returns group
    local group g = CreateGroup()
    call GroupEnumUnitsInRangeOfLoc(g, whichLocation, radius, filter)
    call DestroyBoolExpr(filter)
    return g
endfunction

well fuck is there any way to use this function in GUI without it leaking

or do i have to use something else

local ref-counted object variable problem: Ref-counted are not fully released until all refs have vanished but local variables in jass are not reset in that aspect when they go out of scope -> reference persists and object can never rest in peace.

i have no idea what any of this means, can you give an example of where this occurs in my triggering and how to fix it

Seeing your multiboard cell setting functions, which are very ineffective implemented in GUI btw, afaik the multiboarditems that get allocated and deallocated there are also ref-counted.

i don't know what this means either, i might just disable the multiboard because it's useless anyway

In some places you convert a player to a player group, which creates a new object and do not destroy it afterwards.

again, can you give an example of where this occurs in my triggering and how to fix it

string table pollution through concatenation: every string ever created is parked in some global data structure (this is not really something you can avoid other than try to reduce the appearance of new strings), accessing the same string over and over is okay

is this what you mean??

  • test
    • Events
    • Conditions
    • Actions
      • -------- this leaks? --------
      • Game - Display to (All players) the text: (Here is + a message)
      • Game - Display to (All players) the text: (Another + message)
      • -------- this doesn't leak? --------
      • Set msg[0] = Here is
      • Set msg[1] = a message
      • Game - Display to (All players) the text: (msg[0] + msg[1])
      • Set msg[0] = Another
      • Set msg[1] = message
      • Game - Display to (All players) the text: (msg[0] + msg[1])
 
Take a look at these tutorials about leaks. Do not feel intimated by the wall of text, it is an extremely easy concept to learn and takes about a minute of your time to fix in your trigger functions.

If you want to see which trigger functions leak and how to fix them, read Ralle's tutorial. If you want a more detailed explanation of leaks, read IcemanBo's.
 
Level 26
Joined
Aug 18, 2009
Messages
4,099
well fuck is there any way to use this function in GUI without it leaking

The function is the problem, no matter how you call it. You could for example write a custom function:

JASS:
function GetUnitsInRangeOfLocMatching_custom takes real radius, location whichLocation, boolexpr filter returns group
    set udg_g = CreateGroup()
    call GroupEnumUnitsInRangeOfLoc(g, whichLocation, radius, filter)
    call DestroyBoolExpr(filter)
    return udg_g
endfunction

where udg_g refers to a global group variable (in GUI variable editor without the udg_ prefix) and then invoke that function from your GUI triggers via custom scripts.

i have no idea what any of this means, can you give an example of where this occurs in my triggering and how to fix it

That paragraph referred to the GetUnitsInRangeOfLocMatching function. It defines a local variable and binds the group CreateGroup(). Local variables are allocated during runtime (put on a stack), one for every call you make to that function. While the memory it uses up is restored as soon as the function returns/is terminated, it does not automatically inform the object to decrease the reference count, therefore once a local variable dies without being nulled, the count won't be able to become zero again.

i don't know what this means either, i might just disable the multiboard because it's useless anyway

Basically the same as with the unit group, only that in GUI you do not deal with the type "multiboarditem" directly, you instead only state column/row coordinates.

again, can you give an example of where this occurs in my triggering and how to fix it

Just go to >Object Manager >Functions >Function Calls >Convert Player To Player Group

It's a rather common mistake, probably because GUIers think that players are static and therefore player groups would have to be or just because it's not as frequently mentioned.

is this what you mean??

You do create strings there, however, those are literals and concatenated in a fixed arrangement only, so you get but a few combinations. What is problematic is something like

  • Set s = ((String((Random real number between 0.00 and 1000000.00))) + (Name of (Triggering unit)))
ran over and over, creating lots of variations. However, unless you exaggerate it, that won't do much. It may usually only be an issue if you have extended string manipulation like dynamically composing save codes, running text, parsing etc.
 
Level 12
Joined
Mar 21, 2008
Messages
375
Take a look at these tutorials about leaks. Do not feel intimated by the wall of text, it is an extremely easy concept to learn and takes about a minute of your time to fix in your trigger functions.

If you want to see which trigger functions leak and how to fix them, read Ralle's tutorial. If you want a more detailed explanation of leaks, read IcemanBo's.

thanks, i wasn't even aware of some of the stuff described in iceman's tutorial

The function is the problem, no matter how you call it. You could for example write a custom function:

JASS:
function GetUnitsInRangeOfLocMatching_custom takes real radius, location whichLocation, boolexpr filter returns group
    set udg_g = CreateGroup()
    call GroupEnumUnitsInRangeOfLoc(g, whichLocation, radius, filter)
    call DestroyBoolExpr(filter)
    return udg_g
endfunction

where udg_g refers to a global group variable (in GUI variable editor without the udg_ prefix) and then invoke that function from your GUI triggers via custom scripts.

ok so this good right

stuff in map header:
JASS:
function SomeCondition takes nothing returns boolean
    return ( IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == true )
endfunction

function GetUnitsInRangeOfLocMatching_custom takes real radius, location whichLocation, boolexpr filter returns group
    set udg_g = CreateGroup()
    call GroupEnumUnitsInRangeOfLoc(udg_g, whichLocation, radius, filter)
    call DestroyBoolExpr(filter)
    return udg_g
endfunction

  • unit group
    • Events
      • Time - Every 0.01 seconds of game time
    • Conditions
    • Actions
      • Set loc[0] = (Position of Footman 0000 <gen>)
      • Custom script: set udg_unitgroup[0] = GetUnitsInRangeOfLocMatching_custom( 512, udg_loc[0], Condition(function SomeCondition) )
      • Unit Group - Pick every unit in unitgroup[0] and do (Actions)
        • Loop - Actions
          • Do nothing
      • Custom script: call DestroyGroup(udg_unitgroup[0])
      • Custom script: set udg_unitgroup[0] = null
      • Custom script: call DestroyGroup(udg_g)
      • Custom script: set udg_g = null
      • Custom script: call RemoveLocation(udg_loc[0])
      • Custom script: set udg_loc[0] = null
also uh i noticed that if you don't null locations/groups even after destroying them, wc3's memory usage goes up

is that because it's a reference leak? should i be nulling locations/groups after destroying them from now on?

edit: ALSO i'm guessing GetUnitsInRangeOfLocAll shouldn't be used either, right?
 
Last edited:

Dr Super Good

Spell Reviewer
Level 65
Joined
Jan 18, 2005
Messages
27,296
also uh i noticed that if you don't null locations/groups even after destroying them, wc3's memory usage goes up
Memory is a bad indication of leaks because of how virtual memory functions. It might rise continuously due to functions such as replay command saving or caching of graphics elements. WC3 almost always crashes due to the other side effects of leaks long before it runs out of memory error.
 
Status
Not open for further replies.
Top