System GTrigger Event System

I can only assume that:
call TriggerRegisterPlayerUnitEvent(trig,GetLocalPlayer(),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
would cause desynchs in multiplayer maps. I don't feel like testing if it would cause desynchs. Let me know if it doesn't.

I'll repeat that one test with the exact same BJ inlined immediately. Obviously it has no impact on the other test whatsoever. Of course, this test is irrelevant in the first place. -.-

Edit:
But before I go run this test, I need to make you feel a little silly for making me do it...
  • DestroyTrigger clocked at ~6 nanosec on my computer. GTrigger's register event function is faster (at ~4 nanosec). So I don't see why you're making me do this. It's faster than a commonly used and quite fast native.
  • A basic function call is under 1 or 2 nanosec (do keep in mind these speeds are all on my computer, in case you test them yourself, but the percentages differences should be right). The margin of error on the BJ was 30 nanosec. The different will be within margin of error, making it undetectable.
  • The different is 100x. Do you think it's going to be suddenly faster? Or even down to 50x?
Anyway, I'll be back with the results in 10 minutes.

Edit: Sorry, 10 mins turned into 30. I found some strange things.

Firstly, I optimized the test as tight as possible, basically...
JASS:
local trigger t=CreateTrigger()
local integer i=bj_MAX_PLAYER_SLOTS
loop
    set i=i-1
    call TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
    exitwhen i==0
endloop

Very aware this leaks a trigger, as it is meant to. The triggers are supposed to persist, and such, like in a real situation.

Now initially I tested over 10,000 executions, and got that massive result.

This time I first tested over 2,000 and as I ran the test over and over, I found out that the time was going up. I mean... I hit F10 --> restart map basically and the time continued going up from when it left off. I restarted WC3 and the process repeated. There seems to be some very serious leaks to do with trigger events here, or something. They didn't get flushed out when the map was restarted or something. I honestly don't know what.

Anyway, on a fresh restart of WC3, and a run of 100 executions, GTrigger was ~4-5 nanosec and that optimized code above was ~32 nanosec. This is a realistic example.

But more puzzling is that example I listed. It actually takes longer and longer, each time it is called, until WC3 is restarted? I'd love for other people to test this, if they are considering it.

Anyway, so I'll say the old method runs as a cool 32 nanosec, as opposed to my obtained value of 470 before. So GTrigger is still about 7 times faster. :)

But! If this effect really persists like that (until WC3 is restarted), then adding events unnecessarily is really quite bad. So this is yet another reason to use GTrigger. :)
 
would cause desynchs in multiplayer maps. I don't feel like testing if it would cause desynchs. Let me know if it doesn't.
I've once heard that it should work, however I've never personally tested it, neither have I ever been comfortable using it. However if it works you cant get a faster native alternative. I'll log on later and test it out.

I'll repeat that one test with the exact same BJ inlined immediately. Obviously it has no impact on the other test whatsoever. Of course, this test is irrelevant in the first place. -.-
If those results are irrelevant I don't understand why you posted them in the first place.

But before I go run this test, I need to make you feel a little silly for making me do it...
You aint never going to make me feel silly about questioning either your results or methods.
 
I've once heard that it should work, however I've never personally tested it, neither have I ever been comfortable using it. However if it works you cant get a faster native alternative. I'll log on later and test it out.

I remember that there was some reason why you should not use it. ( Gotta check wc3c , I dont quite remember )

Anyways, having only your own event in your computer, but not other players events, feels quite dangerous.
 
JASS:
call TriggerRegisterPlayerUnitEvent(trig,GetLocalPlayer(),EVENT_PLAYER_UNIT _SPELL_EFFECT,null)


Player 1 will have the event registered for his own units, but not other player's units.
Player 2 will have the event registered for his own units, but not other player's units.

If Player 1 casts the spell the event is triggered on his computer, but not Player 2s. Hmm. Sounds like a desync to me.
 
That was my assumption. Especially because in single player maps, when you code for player 2 casting a spell, it works and fires on your machine.

>You aint never going to make me feel silly about questioning either your results or methods.

Fine by me. *Shrugs*

>I remember that there was some reason why you should not use it.

I'd be curious to hear more on it.


... So the point is, GTrigger is the fastest... XD
But the real reasons to use it are listed in the "pros" section of it's internal documentation thingie at the top. :thup:
 
i dont understand how you benchmarked casting 100 (or so) abilities at a time???

nor do I really see an explanation
 
That is more the response I expected. :)
In case you're wondering how I tested the firing, there's a spell that fires IMMEDIATELY on unit death (as in, if you call KillUnit, the triggers for that spell will fire before the next line of code is run), and that's Phoenix morph. So I simply registered 50 abilities on that spell effect, then started a stop watch, killed a phoenix, and clocked the stop watch. Each test repeated this 50 times, and I repeated each test about 5 times. I then reduced that 50 to 20, still being slower I reduced it to 5, then 2, then 1 failing trigger and 1 working trigger (both attaching using conditions only). Quite a reliable, appropriate test. :)
Just to clarify that, all triggers in my bench test attached with a single condition only.
Ok, to make this any clearer... I triggered 50 triggers on when ability 'A00F' is cast (doesn't actually exist, just to add the effect of having 50 abilities in the map) and 1 trigger fired off when Phoenix Morph was cast (by cast I mean SpellEffect). This means when I call KillUnit on any Phoenix, all 51 triggers fire immediately. I can therefore time that Kill action, and compare it to if I implemented the same stuff using GTrigger. Of course, it has the overhead of the Phoenix turning into an egg and such, but that's not important, because it is assumed to be constant.

When I did the test, the traditional method registered at about 1300 nanosec initially, while GTrigger registered at about... 470? I forget. Long story short, when there were no triggers except the one firing on Phoenix Morph, the traditional method was faster. When there was that one AND one firing on 'A00F', the GTrigger method was faster. And adding more firing on a separate ability added more and more delay to the traditional method, as predicted.

Hence, the answer, is 2.

From 2 abilities in the map, GTrigger is faster. Therefore, every map with triggers firing off abilities should use it. Well, that's my logic. :)

If people want to design other tests, I welcome it. If you can find any result, similar or different, I'd love to hear about it.

Furthermore, if you want to review my test more carefully, I can upload them...

All I can say... is APPROVE MAH SYSTEMZZOR! :D

PS. Actually, here's the test. Take a look. Let me know if you really must see it with any certain modifications.

PPS. Yeah, not casting 100 abilities at a time. At all. Just casting one ability 50 times, in a map with "50" abilities (and then 20, 5, 2, and 1).
 

Attachments

  • BenchSys.GTrigger.VS.Normal.zip
    112.5 KB · Views: 436
This needs a demo map demonstrating it's usage.
 
The only problem I have is this:

JASS:
call TriggerRegisterPlayerUnitEvent($NAME$Trigger,Player(i),EVENT_PLAYER_UNIT_$EVENT$,null)


"null" leaks. You would need a global variable so

JASS:
globals
private filterfunc non_leaking_filter = null
endglobals

private constant function DummyFilter takes nothing returns boolean
    return TRUE
endfunction

set non_leaking_filter = Filter( function DummyFilter )
call TriggerRegisterPlayerUnitEvent(whichTimer, whichPlayer, whichEvent, non_leaking_filter)


Dark_Dragon said:
boolexpr is like a table with condition you typed ~via Filter() or Condition() well since script does not know what pointer null is since it will not have table, the leak in memory is created because it will allocate something because you typed null and that something is some part of memory which can contain some data as well but will never again, until you leave the game. So the only thing you have to do is a valid boolexpr table, in your case it should only do nothing (no condition) in trigger registration so do it like next:

we must NOT destroy that filter and we can use that filter unlimited number of times you don't have to make it private if its in your map.

That, added to the fact every event is processed through this system, will effectively create a boolexpr table best suited for its purpose.
 
'null' doesn't leak in trigger registry. I never really understood why, but it doesn't. Blizzard likes to mess with us.
 
If you could point me to a valid test I would be very, very glad, as I'm in fact tired of "wondering".

But, for now, this guy's summed it up quite well.
 
I would love to, but the thread is... lost in time? I don't even remember the name or author. It wasn't too old, but what was it?!

EDIT: Got it! The search button is magical!
 
Well, the conclusions drawn by the last poster are pointing towards a bigger memory usage when using null than a function. In an event. ;)

That isn't quite the results the others got though.
 
I don't take people's word at face value anyway, so when you say "they leak", I investigate further, ignoring the heresay.

But I don't even need to, for null events. I have a beautiful test for this, which is being overlooked. I know for a fact that events with null boolexpr for player unit leak into other maps, even. See the previous posts in this thread, I already prooved it by writing a speed test for adding an event, and it keeps taking longer and longer to add the event, until I restart WC3 - even restarting the map does not reset the speed it takes to add an event.

I do not know yet if adding the "return true" filter/condition changes anything. I'm happy to try that out when I get home to proove one way or the other, and update GTrigger if need be.

Ultimate fact: GTrigger does not have these problems as the leaks are capped because a fixed number of events are created. This is yet another reason to use GTrigger.

To-do:
  • Investigate the null boolexpr leak and publish my results here.
  • Upload a test map for this system's approval.
 
Seems as a very nice system, looking forward to the updates!


Though, the only thing that bothers me is the way you name your variables.

They should be short and explanatory, instead of long sentances saying what the variables exactly does.

Not like it affects performance, but it looks weird to me. :)
 
Thanks, Andrew.

In regards to variable names, I do that because they're actually globals, simulating locals (in one situation I had to make them actually locals, because the function could end up being recursive). So I add parts of the function names to the start to make sure I don't mix things up.

Why don't I just use locals? Because deep down, my belief is if it's easy to make more efficient, do it. Initializing a local and setting it takes twice as long as setting a global. :eek:

I would never recommend anyone to code like this, but I like to in my systems, because the penalty of my style is not passed on to the user in any way, just the tiny, tiny, efficiency bonus. :rolleyes:

To-do:
  • Investigate the null boolexpr leak and publish my results here.
  • Upload a test map for this system's approval.
  • Add AnyUnitDies style event. :D
I swear, I'll get around to it some time! Holidays start after tomorrow! ;)
 
Add AnyUnitDies style event.

hm..?

What this has to do with spell events?

Why don't I just use locals? Because deep down, my belief is if it's easy to make more efficient, do it. Initializing a local and setting it takes twice as long as setting a global.

If you have loads of globals, it slows them all down. But yea, its probably still faster.
 
>What this has to do with spell events?

Who said GTrigger was limited to spells? :D

>If you have loads of globals, it slows them all down. But yea, its probably still faster.

Hang on, we're talking about a game engine where people freely declare arrays of size 8192. I'm talking about 10-20 globals. ;) I don't even know if what you're saying there is true. :p
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Varine Varine:
    We have some elderly guests that regularly come hang out at the bar at the end of the night, and every once in a while we don't see someone for a few weeks and then someone shows up with their obituary.
  • Varine Varine:
    We usually let them do their memorials there in the morning if they want to and I'll make them some snacks and drinks. There was one guy named Tom that came in like every night and would sit by himself and get a bunch of soup and a glass of wine. idk why but he LOVED our fucking soup, like he would order a fucking quart of it at a time and would always get so sad when we stop doing it for the summer.
    +1
  • Varine Varine:
    But he also loved our calamari, which is another thing I hate but it sells super well so I can't change it. There was one day he came in and was asking me how to make it, because he tried to at home once in the off season when we stop running it and he really wanted it lol
  • Varine Varine:
    I think he's one of the only people I've made recipes for for free because he really wanted a broccoli cheddar, and it was like dude I don't have a recipe, it's just whatever I have, but here, this is how you do it
  • Varine Varine:
    I don't think he ever figured out how to do the calamari in a pan though, like idk how to do that either. He was afraid of the at home deep fryers though and it's like yeah, that's fair, I am too
  • Varine Varine:
    He was just such a sweet old man, we had two servers pregnant and they held a baby shower together, he was soooooo fucking excited to get to see a baby. Unfortunately he died a month or so before they were born
  • The Helper The Helper:
    So I decided to Google some people that I had not seen or heard from in a while and sure enough one of my old best friends, we had a falling out years ago but whatever, find out he died of Pancreatic Cancer in January. I have also lost a few of my closer acquaintances from growing up the last year. Getting old - people die - I kinda thought it was going to be this way a few years ago....
    +2
  • The Helper The Helper:
    Forum running super slow again
  • Ghan Ghan:
    Not really clear from the stats as to what is causing the slowness.
  • Ghan Ghan:
    We get a lot of guest traffic so it may just be the load is getting too high and not from any particular source.
  • Ghan Ghan:
    Looks like the server is maxed out on CPU.
  • Ghan Ghan:
    Oh it looks like a lot of the traffic is Silkroad Forums. That domain isn't protected by Cloudflare.
  • Ghan Ghan:
    But the old Silkroad site is still on its own server. I just had a test site set up on this server for it.
  • Ghan Ghan:
    I just disabled that test site. Let's see if that helps the load.
  • Ghan Ghan:
    Looks much better already.
  • The Helper The Helper:
    I had actually forgot about the Silkroad site. I had asked
  • The Helper The Helper:
    SD Ryoko about it and he said the couple of people left on there really like it, that was a few years ago, maybe I should check back
  • jonas jonas:
    I guess when you're getting old, and the last day of soup season draws near, you start wondering
  • jonas jonas:
    will I make it to the start of the next season? or was this the last time I'll ever have my favorite dish?
  • The Helper The Helper:
    I am doing my first Vibe Coding project. In installed the environment and tools according to instructions but it is all chat doing this for me at my direction. It is fun really and holy shit I might finish in 2 hours what it would have taken a day to in my Access and this would be an electron app complete new
  • Ghan Ghan:
    Good stuff.
  • Ghan Ghan:
    Just make sure it is secure. :)
    +1
  • The Helper The Helper:
    It will only be on internal network
  • jonas jonas:
    Man the AI is good about gaslighting about security though. I've had several times where I pointed out security problems and it tried to convince me that with a tiny tweak it suddenly becomes secure
  • jonas jonas:
    Like using a distrobox as a "secure" container, and when I point out that's not secure at all, it claimed that specifying home will make it secure

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials
      Top