• 🏆 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!

[JASS] What to do with triggers?

Status
Not open for further replies.

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,178
Try and recycle the triggers as much as possiable. In the end some destruction is going to be needed but try and reduce it to a minimum as destroying triggers can cause a game crash some times. Letting triggers leak is also bad so it is not reccomended to do that as well.

Timers on the other hand you can destroy pretty safely generally. However if they are preodic they can result in the running of a function an extra time. Try and use eithor a constant timer for a system or else a timer recycle system as both of these eliminate the problem. You can also just destroy the timer but that is up to you.
 
Level 5
Joined
Dec 20, 2008
Messages
67
Hello :p

I've read around here that destroying triggers or timers is not good.
So, what do I do with local triggers created when I need a missile to go boom when they hit a unit? Let it leak?

Thanks already!
Hossomi

you dont need such triggers at all except for damage detection systems...

just periodically enum units around your projectile ...and if the target is in range .....do your stuff
 
Level 19
Joined
Aug 24, 2007
Messages
2,888
I dont have a problem with destroying triggers
as I cant actually remove an event I have to destroy the trigger
and Im happy with it ^_^
you should be too

And checking units in 10000 range every milisecond wont lag
 
Level 14
Joined
Nov 18, 2007
Messages
816
I dont have a problem with destroying triggers

Well, you should. Theres a reason why DestroyTrigger() was banned, you know. And unless you can ensure your code doesnt destroy triggers that are still running, you might blow up everything (Note: this only refers to known bugs, there might be other bugs that are not uncovered yet).

Another thing: if you are using dynamic triggers (triggers, whose data is modified during runtime) for anything else than damage detection, youre doing it wrong.
 
Level 5
Joined
Dec 20, 2008
Messages
67
Deaod, I have no idea what you mean.
The actual problem is a handle allocation bug which causes a game crash, however it occurs seldomly as long as you minimise the ammout of trigger destruction.

It doesnt have to cause a crash, at all ...it could just fuck up some triggers of your map, eventually make some spells malfunction...dependant on the maps code (and luck) it may of course cause a crash.

But deaod is right, why risk to fuck up your map, when there are better ways to do this, without any risk of causing bugs ?!

The only thing what you cant achieve without dynamic triggers is damage detection .... unless you have a unit recylcing system ..but such a system would be really unpractical
 
Level 19
Joined
Aug 24, 2007
Messages
2,888
blablabla
you have no idea what you are talking about
shut up and DO NOT EVER try to teach me something again

P.S. I Always keep Any Unit Takes Damage system in my maps
Actually I have my master system with many systems in it and I use it in my ALL maps and never got any problems with it
 
Level 14
Joined
Nov 18, 2007
Messages
816
@Need_O2: go ask Rising_Dusk about dynamic triggers. I believe he had some ... interesting experiences with them in AotZ.

You really should learn to listen, perhaps you can learn something new (to you). If youre using dynamic triggers, go ahead. I can't stop you. But i can tell you, that there are almost always ways around dynamic triggers (except for damage detection, e.g.). And destroying triggers does cause bugs, so you should NEVER do it. Leaking a few events is an adequate price for avoiding fatal bugs.

Btw: Telling me i dont have a clue what im talking about isn't exactly smart, you know. I know for a fact that destroying triggers CAN cause bugs.
 
Level 19
Joined
Aug 24, 2007
Messages
2,888
I know to listen to PEOPLE WHO KNOWS SOMETHING
Im sick of people that doesnt even have a clue of what they are talking about but they try to teach me something

Yes YOU ARE ABSOLOUTLY RIGHT
Removing units ? no problem
Removing Destructables ? no problem
Removing Weather Effects ? no problem
etc etc etc...
Removing Triggers ? OH NOOOO

So why removing every type of handle in warcraft is fine but triggers
I dont even care about what Rising_Dusk thinks
I dont even care about what you say
None of you made Warcraft III
none of you have a CONVINCING proof

Yes sure Fatal bugs
Which Ive never encountered

Suggestion: go play your Need for Speed and Fifa and stay out of my business
 
Level 14
Joined
Nov 18, 2007
Messages
816
Removing units ? no problem i wouldnt advise you to do it, though there are no know bugs caused directly by RemoveUnit()
Removing Destructables ? no problem I havent heard of a bug yet
Removing Weather Effects ? no problem same here
etc etc etc...
Removing Triggers ? OH NOOOO Indeed.
So why removing every type of handle in warcraft is fine but triggers
You forgot about timers and groups.

I suggest you try to search for those bugs, before you say they dont exist. They do exist.
 
Level 19
Joined
Aug 24, 2007
Messages
2,888
I forgot timers and groups ? OMG
rect, region, camerasetup, fogmodifier, quest, gamecache, dialog, boolexpr, filterfunc, location, item and more I cant remember
and "etc etc etc..." was for other handles

Can someone tell this guy to stay out of my business please ?

Edit: Why do I even care...
 
Level 14
Joined
Nov 18, 2007
Messages
816
bah, you have no idea.

Wc3campaigns - View Single Post - Known bugs in JASS

Maybe i didnt express myself correctly:

Destroying timers and groups also can cause bugs (in the case of timers) or leaks (in the case of groups).

Edit:
@Need_O2: If you still haven't followed that link, do it. You asked for evidence, and there it is. You tell me i have no idea and when i give proof for my claims, you say you dont care in the first place, ignoring my proof. Well, youre fucking with your map, and not mine. I dont care. But dont tell me i have no idea.
 
Level 19
Joined
Aug 24, 2007
Messages
2,888
so it says
If you destroy a trigger inside it while it has remaining actions and wait(0) 2 times (one after another) and create 2 groups at same time those groups will be same...
what a bug....

I was expecting something like if you create/destroy a trigger 100000 times in a game, game will crush
or destroying a trigger causes some quests to change their texts
or destroying too many triggers causes a random unit to lose life
or destroying soo many triggers kicks someone from game

Simply go away please
 
Level 5
Joined
Dec 20, 2008
Messages
67
you are a pretty dumb ignorant Need_O2 really ...think about what this bug may cause ...

Its not only for groups, the bug will happen for ALL Handles ...it might even mix them up ..and maybe some timer you create becomes a unit handle instead ...no tell me that wouldnt fuck up your map (also there are THOUSANDS other possible bugs that might happen).

And it doesnt have to have those waits in it .... thats only the easiest way to make this bug happen on purpose.
 
Level 19
Joined
Aug 24, 2007
Messages
2,888
I do not require to destroy my trigger inside it while its running and wait(0) 2 times (one after another)

You know what is buggy here ?
its TriggerSleepAction

JUST TELL ME SOMETHING THAT ONLY BE CAUSED BY DestroyTrigger()
no "The most buggy and unaccureate function" TriggerSleepAction inside it
and nothing else
Just a bug by DestroyTrigger()

if you cant shut up

Edit: No answers ? Thought so
 
Level 14
Joined
Nov 18, 2007
Messages
816
those groups will be same...
No, they wont be the same. Their ID will be the same, but the actual objects are distinct from each other.

Me. said:
And unless you can ensure your code doesnt destroy triggers that are still running, you might blow up everything (Note: this only refers to known bugs, there might be other bugs that are not uncovered yet).

Me. said:
Another thing: if you are using dynamic triggers (triggers, whose data is modified during runtime) for anything else than damage detection, youre doing it wrong.
 
Level 19
Joined
Aug 24, 2007
Messages
2,888
None of these things show that DestroyTrigger bugs

I knew TriggerSleepAction is buggy already...
so what Ive learned ?
Using it 2 times is buggy too ^_^

I assume you wont show me a bug of it without another buggy functions such as TSA
cya in another thread

BTW: if you were joking whole time its not april yet :/
 
Level 23
Joined
Nov 29, 2006
Messages
2,482
Why would you destroy a trigger before sleeping it in the first place I wonder? And it seems, regarding my testing that it never occured with only one triggersleepaction (with >=2 it did though).
Hm also, storing the group in a variable instantly after each other and then compare them seems to make the risk smaller.

But yeah, it is buggy that's for sure.
 
Level 19
Joined
Aug 24, 2007
Messages
2,888
Well
I have some

1- If you use TSA in functions executed via ForGroup, it causes thread crash
2- If you use TSA in functions executed via a timer, it causes thread crash

and Its not accurate
shortest pause with TSA is granted with TSA(-1) <I guess it was 0.15 secs
TSA(-2) => 0.25 and TSA(0) => 0.2 as I remember
TSA(1) is like random wait between 0.5 and 1.5 secs

and in the bug proof you sent if you remove TSAs its fine (its fine if you even remove one of them)
 
Level 14
Joined
Nov 18, 2007
Messages
816
both cases are incorrect usage of TSA, and no bug of TSA. As i said, its called TriggerSleepAction, so dont expect it to work in anything else than TriggerActions.

Edit: Guess what: if you remove DestroyTrigger(), theres no bug.
 
Level 19
Joined
Aug 24, 2007
Messages
2,888
Its unaccurate in trigger actions too
will you stop insisting on that please ?
you seem to have blinded yourself
 
Level 7
Joined
Dec 31, 2005
Messages
712
(let me take two steps away from the discussion o.o')

If destroying groups bugs too (just ignore it Need_O2 >.>), enum units in range would require creating/destroying groups. So I guess I haven't reached a solution xD

Anyway, I haven't had any problems with DestroyTrigger() and no other handle destroying functions.
And I use them in almost all my systems.
In my last work there was about 5 missiles per second, each one with a dinamic trigger (I need them to detect units in range, I think it's better than enum units) and destroying it in the end.
I played it for 2 hours, no problems...
 
Level 7
Joined
Jul 20, 2008
Messages
377
There's no bug with destroying groups.

As for destroying triggers, I have yet to confirm for myself that it bugs. I've worked with a damage detection system making heavy use of DestroyTrigger(), and had no problems with the game.

But then again, I don't think I really got that far in that map as to ensure one object was separate from another.

So I'm really interested in this thread.

EDIT: Oh, I see now. DestroyTrigger() only bugs if you destroy a trigger that's still running, correct? So if it's not running, it's safe to destroy?
 
Level 19
Joined
Aug 24, 2007
Messages
2,888
Well... umm... I recycle a single group everytime for things like AoE spells (ForTheAll)
Well and Unit Recycling is a better way for sure, not because of DestroyTrigger bugs but creating destroying trigger each time isnt so healthy ofc

Unit Recycling works like:
you have a footman, when it dies its food cost is disabled it gets hidden and moved to some place named Haven (lol)
When you create another footman, the footman gets repleaced with footman in haven (buffs removed and health filled ofc)
Ofc its a bit more complicated xD but it works like this

Anyway just dont create-destroy much things
 
Level 14
Joined
Nov 18, 2007
Messages
816
I haven't had any problems with DestroyTrigger() and no other handle destroying functions.
You not having run into any bugs doesnt mean there are none.

There's no bug with destroying groups.
No exactly a bug, but once you use certain functions (i think it was ForGroup()) on groups they leak, even when destroyed.

DestroyTrigger() only bugs if you destroy a trigger that's still running, correct?
Thats the most common explanation.

Its unaccurate in trigger actions too
Its accurate enough for GUI, so why bother. If you want more accuracy, go for timers. And i dont consider inaccuracy a "bug". Its more due to the way this function works internally.
 
Level 5
Joined
Dec 20, 2008
Messages
67
DestroyGroup will cause some leaks if you used some special natives for that group before as far i know.
So Recycling them is good...there is a good script named GroupUtils available over at war3campaigns which achieves that and it also got a GroupRefresh function to get rid of ShadowUnits...

Normally you dont need that however, because you can one global group for most stuff...when doing this you shouldnt use ForGroup calls however, do your Actions in the Filterfunction instead (and NEVER use "null" as filter, because it leaks).

And if you really insist on using DestroyTrigger on dynamic triggers, you should destroy them after some time, after the trigger has been run ...(maybe 5-30 seconds, but PLEASE dont use TriggerSleepAction for that delay ...use timers ..4 real).

There are aswell problems regarding destroying timers ..i dont know excactly what it was again ...but i really dont care because recylcing them is faster anyway ....and of course TimerUtils functions (SetTimerData / GetTimerData) are pure awesomness..
 
Level 7
Joined
Dec 31, 2005
Messages
712
Well... umm... I recycle a single group everytime for things like AoE spells (ForTheAll)
Well and Unit Recycling is a better way for sure, not because of DestroyTrigger bugs but creating destroying trigger each time isnt so healthy ofc

Unit Recycling works like:
you have a footman, when it dies its food cost is disabled it gets hidden and moved to some place named Haven (lol)
When you create another footman, the footman gets repleaced with footman in haven (buffs removed and health filled ofc)
Ofc its a bit more complicated xD but it works like this

Anyway just dont create-destroy much things

I think that's just what I need!
I haven't thought about that :p

However I'll use TimerUtils and enum for whatever I need, recycling groups as they suggested.

Thanks you all :p
And please don't kill each other x.o
 
Level 7
Joined
Jul 20, 2008
Messages
377
Sorry to necropost, but I ran a few tests. I don't think DestroyTrigger() really bugs. Why? Because when I tried the DestroyTrigger bug - it would bug when I typed -bug (and even up to like 100 times).

However, when I ran another trigger AFTER running the bug trigger 100 times:
JASS:
function Trig_test_Actions takes nothing returns nothing
    local integer i=0
    loop
        exitwhen i>=20
        if CreateGroup() == CreateGroup() then
            call BJDebugMsg("|cFFFF0000Bug Caught|r")
        else
            call BJDebugMsg("|cFF00FF00No Bug Caught|r")
        endif
        set i=i+1
    endloop
endfunction

//===========================================================================
function InitTrig_test takes nothing returns nothing
    set gg_trg_test = CreateTrigger(  )
    call TriggerRegisterPlayerChatEvent( gg_trg_test, Player(0), "-compare", true )
    call TriggerAddAction( gg_trg_test, function Trig_test_Actions )
endfunction

when I type -compare, there is no bug caught. In fact, I also just modified it so that the bug trigger does not create any groups, and I made -compare only do one check. It did not catch any bugs either.

So I think Need_O2 was right, DestroyTrigger() does not bug at the fundamental level... it's just how you use it. As he said before, TSA was also at fault. So I think there's more to this bug than just DestroyTrigger() and just TSA.

EDIT: Just ran further experiments. Calling a function that destroys the calling trigger does not cause any bugs. Neither does running a concurrent trigger (runs while the main bugging trigger is sleeping) to destroy the first trigger bugged it.

In short, DestroyTrigger() seems to be safe as long as you avoid using waits in the trigger that's being destroyed.
 
Last edited:
Level 23
Joined
Nov 29, 2006
Messages
2,482
It seems that we may be able to avoid the destroytrigger bug by using triggerconditions instead of triggeractions, since these are not threaded. However, it's not certain yet.

And Soga, that wasn't really a necropost.
 
Level 7
Joined
Jul 20, 2008
Messages
377
Dynamic triggers are required for damage detection. I just think the danger of using dynamic triggers is way overblown.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,178
The problem with trigger destruction is a handle index recycle bug which can lead to 2 objects having the same hande (and a crash). Although one really should not fear it, it is advisable to keep the ammount of trigger destruction to a minimal. In damage detection systems, for example, you can reuse one trigger for multiple units before destruction instead of 1 trigger per unit.

This bug does exist, and it mostly causes crashes. However I would say the failed displacement bug is a much more common cause of crashes.
 
Level 9
Joined
Apr 5, 2008
Messages
529
I just tested, and it seems that ResetTrigger doesn't do anything. I tried with both triggercondition's and triggeraction's. TriggerClearConditions and TriggerClearActions worked fine, but from reading the thread you linked, it seems that they still leak when cleared.
Perhaps ResetTrigger resets evaluate/execute count?

JASS:
scope ResetTriggerTest
    
    globals
        public trigger CheckTrig
        
        public trigger TestTrig
    endglobals

private function check takes nothing returns boolean
  call BJDebugMsg("Trigger is running")
  return false
endfunction

private function test takes nothing returns boolean
  call ResetTrigger(CheckTrig)
  //call TriggerClearActions(CheckTrig)
  //call TriggerClearConditions(CheckTrig)
  call BJDebugMsg("Trigger reset")
  return false
endfunction

public function InitTrig takes nothing returns nothing
  set CheckTrig = CreateTrigger()
  call TriggerRegisterPlayerEvent(CheckTrig, Player(0), EVENT_PLAYER_END_CINEMATIC)
  call TriggerAddCondition(CheckTrig, Condition(function check))
  //call TriggerAddAction(CheckTrig, function check)
  
  set TestTrig = CreateTrigger()
  call TriggerRegisterPlayerChatEvent(TestTrig, Player(0), "test", false)
  call TriggerAddCondition(TestTrig, Condition(function test))
endfunction
endscope
 
Status
Not open for further replies.
Top