• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Crash] What is the maximum amount for Triggers/Variables?

Status
Not open for further replies.
Level 8
Joined
Jun 26, 2014
Messages
62
Hi WorldEdit M8s :thumbs_up:

I have a curiosity about the number of Triggers/Variables for every map. I'm asking this because i had 1221 Triggers and 1961 Variables in this map. Now i add a new system, creating 24 Triggers (1245 in total) and 2 variables (1963 in total) to make it works, and for an unknown reason, the map do a "self-corrupts", affecting the normal function into the Triggers. For example:


idkwht10.png


Anyone know the reason? :vw_wtf: I'll wait your answers.

Greetings :goblin_yeah:
 
Level 8
Joined
May 21, 2019
Messages
435
Hi WorldEdit M8s
I have a curiosity about the number of Triggers/Variables for every map. I'm asking this because i had 1221 Triggers and 1961 Variables in this map. Now i add a new system, creating 24 Triggers (1245 in total) and 2 variables (1963 in total) to make it works, and for an unknown reason, the map do a "self-corrupts", affecting the normal function into the Triggers. For example:
Anyone know the reason? I'll wait your answers.
Greetings
There's a million things that could cause this, but I wanna address just how insane 1221 Triggers and 1961 variables is in the first place.
It sounds a lot like you have zero refactoring in your code, especially since you talk about "copy-pasting".

Pyrogasm recently replied to a thread, that having too many "unit enters playable map" and "unit enters entire map" events would mess up the pathing of units. To me, that's just one of many examples of why excessive events should be avoided.

If you were to rework some of your systems to be based on refactoring, you could cut down the amount of triggers considerably. Furthermore, the insanely high amount of variables, makes me think that you are using neither arrays nor temp variables.

Would you be opposed to posting your map source for a bit of a code review? It's very likely that there's a few things that can be optimised extremely easily.
 

Wrda

Spell Reviewer
Level 25
Joined
Nov 18, 2012
Messages
1,864
Pyrogasm recently replied to a thread, that having too many "unit enters playable map" and "unit enters entire map" events would mess up the pathing of units. To me, that's just one of many examples of why excessive events should be avoided.
Then you could try to explain to me why do many maze maps and quite a few slides have a lot of region events and don't break pathing of units. Probably because some of them use regions instead of rects (regions in jass) and add rects to 1 region, but most don't. Well, in fact, they don't use "...enters playable map area" or "entire map". Not to mention 1 map that actually had 4000 regions and I've never seen it breaking pathing of units. And when it breaks (on any map of this kind) it is extremely rare and literally stops a unit after like 30mins since he started patroling or moving non-stop.

There's not much information about your problem, start debugging it and tell us what works and till where it works...and stuff like that. And maybe post your map's triggers.
 
Level 8
Joined
May 21, 2019
Messages
435
Then you could try to explain to me why do many maze maps and quite a few slides have a lot of region events and don't break pathing of units.
You'd have to ask Pyroclasm and DSG for the specifics, but as far as I picked up, this applies exclusively to "Entire Map" and "Playable Map Area", not regions in general.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
Then you could try to explain to me why do many maze maps and quite a few slides have a lot of region events and don't break pathing of units.
Because it is based on the number of cells contained in regions and not the number of regions or their associated events. A single unit enters playable map area event counts a lot more to the limit than all those hundreds or thousands of unit enters tiny maze region events. Ignorant (of this issue) map makers may use dozens of unit enters playable map area events. The issue is made even worse with map sizes such as 480x480 as that is a lot more cells per playable map area to be associated with a region each time.
but as far as I picked up, this applies exclusively to "Entire Map" and "Playable Map Area", not regions in general.
It applies to regions in general. Just playable map area is one of the biggest rects available and hence will produce a region with most of the map cells in it.
 
Level 8
Joined
May 21, 2019
Messages
435
Because it is based on the number of cells contained in regions and not the number of regions or their associated events. A single unit enters playable map area event counts a lot more to the limit than all those hundreds or thousands of unit enters tiny maze region events. Ignorant (of this issue) map makers may use dozens of unit enters playable map area events. The issue is made even worse with map sizes such as 480x480 as that is a lot more cells per playable map area to be associated with a region each time.

It applies to regions in general. Just playable map area is one of the biggest rects available and hence will produce a region with most of the map cells in it.

Insanely insightful! Thanks for the input.
So, it'd be a good habit to make regions as small as possible, right?

Sure, but I don't know why you said excessive events should be avoided, since they don't have much to do with this.
For a variety of reasons. Here's a few off the top of my head:
  • Events will clutter up the stack. Say that you have 100 events each doing 1 action, vs 1 event doing 100 actions. When 100 events is triggered, the game goes through 100 triggers, saving relevant event response data on all 100 trigger runs until they are executed. 1 event however, only has 1 set of event/trigger data.
  • Keeping track of game mechanic synchronization can be a real nightmare when you excessively fragment triggers.
  • Refactoring is by nature going to be shitty when you split different cases in different triggers with different events. This makes it FAR more time consuming to add, edit, and maintain triggers. You also lose out on the option of refactoring code from previous triggers, when no functionality is made generic.
  • Excessive fracturing of functionality leads to worse readability, which makes it harder and more time-consuming to have people review your code.
  • Performance is better with less events, all in all. It depends heavily on scaling, but with lots of rapid events, you will be impacting game performance to some degree, sooner or later. With Reforged, this is likely going to be a far bigger factor than it is currently, so making it a habit to optimize performance, is probably not such a bad idea.
  • The game is old and prone to mistakes. It's generally a good idea to leave as little to the game engine as possible. This example with regions bugging out the pathing is probably just one of many. There may even be issues not yet discovered or noticed. Things like these are usually discovered by people who write clunky code, and they don't always report it.
That's about the gist of it. I get that I am blurring the line between "many triggers" and "many events", but I find that the 2 tend to go hand in hand with the copy/paste design mentality that OP seems to have a bad case of. I don't claim to know exactly how each and every function impacts the performance, but I think a good gut feel on the subject is a good principle in general. I find that the worst impact on performance stems from doing a lot of actions with no time delay. I will usually try to keep heavy computations out of the same time-frame as gameplay, and I will often prioritize spending memory over frequent and potentially performance hindering computations. One such example is a "cast bar" I made earlier today, which is based on 21 strings. I was generating these strings based on fractions, but that required me to loop up to 22 characters per string, which totals 462 loop iterations done more or less instantly. While the actions they were doing were lightweight, the total still came down to a good split second frame freeze whenever this action was run. Now, I wanna keep that out of the gameplay, as a quick frame lag like that is rather jarring, so I went ahead and saved the strings in an array instead, so that I don't have to construct the array on the fly instead. This is why keeping track of your events is important, because you want to avoid having heavy processing like this, all happening at the same time, or at a point where the gameplay needs to be 100% smooth.
With OP having 1245 triggers, I'd imagine it's nearly impossible to even keep track of the load balancing at all anymore. That's why I'd discourage the heavy use of events, it builds up a technical dept, and sooner or later, it starts to mess things up. Now, not only does nobody have any real idea what exactly is causing OPs issues, but whoever ends up solving this (if anyone), will have to read through 1450 triggers or so...

DFG* is better :)
Agreed. :D
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
So, it'd be a good habit to make regions as small as possible, right?
Yes. But be aware that by "region" I am referring to JASS region. GUI has no wrapper for this type.

The GUI type called "region" is actually a JASS "rect". Rects do not suffer this problem as they define an abstract area of the map.

The GUI event "A unit enters..." internally creates a region containing cells which make up an approximation of the passed in rect.
The game is old and prone to mistakes. It's generally a good idea to leave as little to the game engine as possible. This example with regions bugging out the pathing is probably just one of many. There may even be issues not yet discovered or noticed. Things like these are usually discovered by people who write clunky code, and they don't always report it.
The engine will not make mistakes as it is being run on a computer. Yes it can make mistakes but statistically the chance is insignificant as otherwise computers would be crashing all the time.

The engine can be buggy at times which is likely what you are mentioning. That said as long as you do not run into these bugs you are free to push the limits to whatever is reasonable. For example Warcraft III will (should...) not crash when 4,000 units are attacking each other at the same time, but it might perform so badly the map is as good as unplayable. It will still function correctly and the end results will still be what can be estimated, however the performance until the results are met are not a usable experience.

If one wants to reduce the trigger count and improve trigger script efficiency then I recommend learning Lua or JASS. One can perform a lot of optimizations and scripting practices with those that can reduce the resulting script bloat dramatically. Simple things like bundling multiple actions into a function instead of copying them hundreds of times can potentially save thousands of lines of script and make modification to those actions take a couple of seconds instead of hours.
 
Level 8
Joined
May 21, 2019
Messages
435
Yes. But be aware that by "region" I am referring to JASS region. GUI has no wrapper for this type.

The GUI type called "region" is actually a JASS "rect". Rects do not suffer this problem as they define an abstract area of the map.

The GUI event "A unit enters..." internally creates a region containing cells which make up an approximation of the passed in rect.
Thanks for clarifying.

The engine will not make mistakes as it is being run on a computer. Yes it can make mistakes but statistically the chance is insignificant as otherwise computers would be crashing all the time.

The engine can be buggy at times which is likely what you are mentioning. That said as long as you do not run into these bugs you are free to push the limits to whatever is reasonable. For example Warcraft III will (should...) not crash when 4,000 units are attacking each other at the same time, but it might perform so badly the map is as good as unplayable. It will still function correctly and the end results will still be what can be estimated, however the performance until the results are met are not a usable experience.
What I mean more specifically, is that my experience is that the game will fail to perform smoothly unless it has a failsafe system supporting it, especially when it comes to timing and synchronisation of game events. The poor accuracy of "wait" is a great example of this, but I think it applies to just about anything that relies on assumed chronological execution. I could, in theory, expect events A, B, and C to trigger in that order, based on disconnected events that "should" allign just right, but in distrust of how the game handles delicate timing, I'd much rather ensure this order, by running these triggers through a separate execution trigger, to ensure that the order ends up being exactly as intended. I think it's good practice to not base your designs around underlying architecture in general, as it becomes far more vulnerable that way. Some of the recent patches would be a decent example of this, as they broke a lot of old maps relying on the underlying game handling their game mechanic logic, rather than defining it themselves. I also tend to avoid needlessly burdening the system with pointless trigger executions. Fast periodic events is something I moderate very harshly, for example. It's often much better to simply run these things manually, not just because it's smoother, but because it can be a very bad habit to leave a hundred periodic events firing at all times for no particular reason. I also take issue with performing very large tasks during gameplay, as the game can't load balance it due to gameplay chronology, so I think it's important to keep load balancing in mind as well.
All of these are examples of what I mean, when I say that I recommend not leaving the tedious details for the game engine to handle, as it will often either fail to do so, or perform very badly because of it. Not designing a map to have 4000 units engaged in combat is an example of this, albeit a fairly obvious one.
This may be excessively conservative for Warcraft 3 at the moment, with how powerful the average PC is compared to what was expected to run the game originally, but I have a feeling that performance optimisation is going to play a much bigger role in Reforged, so I like to keep that in mind.

If one wants to reduce the trigger count and improve trigger script efficiency then I recommend learning Lua or JASS. One can perform a lot of optimizations and scripting practices with those that can reduce the resulting script bloat dramatically. Simple things like bundling multiple actions into a function instead of copying them hundreds of times can potentially save thousands of lines of script and make modification to those actions take a couple of seconds instead of hours.
I generally don't like using JASS in the editor. I don't find the syntax to be very well thought through. For example, it'd make a lot more sense if every object that needs to be cleared from the memory, had a function attached to a class, rather than every single type of object having a separate function... like... instead of "Call RemoveLocation(udg_location)", why not just use "udg_location.remove()" That way, you wouldn't have to look up the exact format for every single object type that you are cleaning up. Granted, I don't know much about how JASS works, I just use it whenever nothing GUI is available...

As for functions, I kinda just do those with triggers. You can use variables for arguments and return values, and then just run the trigger as you would a function. I think you can refactor code just fine in the GUI this way. Hell, most of the time, all you need is just a bit of a dynamic design, instead of one that declares 100 different scenarios explicitly. Granted, it's a bit clunkier to write "functions" in GUI than JASS, but you have the advantage of it being 100% GUI, which is just easier to work with, unless you've actually bothered memorizing the majority of the JASS syntax, which is a point that I'd wager takes a good year of coding to really get to. I personally find GUI to be easier to maintain, and it's a lot easier to hand someone GUI based code, than JASS. The deep layered actions can be a pain in the ass, sure, but I tend to just assign that stuff to a variable instead, so I don't have to redo the whole thing when I make a change at a higher layer of dropdown items.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
I generally don't like using JASS in the editor. I don't find the syntax to be very well thought through. For example, it'd make a lot more sense if every object that needs to be cleared from the memory, had a function attached to a class, rather than every single type of object having a separate function... like... instead of "Call RemoveLocation(udg_location)", why not just use "udg_location.remove()" That way, you wouldn't have to look up the exact format for every single object type that you are cleaning up. Granted, I don't know much about how JASS works, I just use it whenever nothing GUI is available...
Because the behaviour is exactly like C. The language does not support concepts such as classes, just like C. Instead destructors and allocates are separate functions, just like C.

A lot of old languages were like that and many are still heavily in use.
 
Level 8
Joined
May 21, 2019
Messages
435
Because the behaviour is exactly like C. The language does not support concepts such as classes, just like C. Instead destructors and allocates are separate functions, just like C.

A lot of old languages were like that and many are still heavily in use.
Ah, well I am certainly no expert in C, it predates my coding experience.
The fact that many of the C-era languages are still in use, is something that I'd consider a problem, but I am well aware of the fact that a large portion of the world's IT runs on legacy code, as I am regretably forced to work with that rather often.
 
Level 38
Joined
Feb 27, 2007
Messages
4,951
The fact that many of the C-era languages are still in use, is something that I'd consider a problem
The vast majority of data gathering and analysis modules in the physics world rely on heavily-optimized FORTRAN code that has been performing well since it was written decades ago. If it ain't broke, don't fix it; there's simply no reason to change because then everything would have to either transpile the FORTRAN or run it externally, and the main advantage it has is that it's basically as optimized (hardware wise) as can be.
 
Level 8
Joined
May 21, 2019
Messages
435
The vast majority of data gathering and analysis modules in the physics world rely on heavily-optimized FORTRAN code that has been performing well since it was written decades ago. If it ain't broke, don't fix it; there's simply no reason to change because then everything would have to either transpile the FORTRAN or run it externally, and the main advantage it has is that it's basically as optimized (hardware wise) as can be.
I think we have very different professional perspectives on this.
I work in a sector where our department alone has a portfolio containing hundreds of systems. Some of those were written decades ago with few to nobody available who actually know or understand how they work. Some of them are major blockages for integrations of other systems, some of them are so limited in their capacity for further development, that entire systems have been build to offer the missing functionality externally. This creates a shitstorm of data-synchronization issues across massive systems hosted on different servers with different integrations, different maintenance schedules, different design philosophies, different data-architechtures, and so on.

If it ain't broke, don't fix it?
Maybe that rings true for some things. But just because a thing isn't broken, that doesn't mean that it isn't an obstacle. There's an entire parallel universe in IT that revolves around legacy software being kept alive by those with massive systems relying on it. Take Internet Explorer 8 for example... Microsoft have been wanting to kill that thing for so long, but they've been paid not to, until they recently caved in and denied supporting it.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
Maybe that rings true for some things. But just because a thing isn't broken, that doesn't mean that it isn't an obstacle. There's an entire parallel universe in IT that revolves around legacy software being kept alive by those with massive systems relying on it. Take Internet Explorer 8 for example... Microsoft have been wanting to kill that thing for so long, but they've been paid not to, until they recently caved in and denied supporting it.
Rewriting code for minimal gains is not economical. Sure it might be easier to use, run faster or become a pleasure to maintain, but that same effort could be spent somewhere else like writing a new piece of software.
 
Level 8
Joined
May 21, 2019
Messages
435
Rewriting code for minimal gains is not economical. Sure it might be easier to use, run faster or become a pleasure to maintain, but that same effort could be spent somewhere else like writing a new piece of software.
Minimal gains? Legacy software support is a multi-billion dollar industry.
I have worked on projects entirely designed to augment features for old legacy systems, with budgets in the hundreds of millions.
Trust me, you'd be shocked to discover how deep the rabbit hole goes on some of these. A new tendency is emerging in which systems are being replaced, rather than given integrations to addon systems, but it's already quite a mess from several decades of "if it ain't broke, don't fix it", so there's a long way to go on some of these.

I get that rewriting code for the sake of rewriting code is silly, but sometimes, it's faster to build a bridge, than to row across a river every day.
 
Status
Not open for further replies.
Top