System Key Timers 2

Cohadar

master of fugue
A few advices for KT2:

You can optimize your load function by preloading triggerExecCount

Since triggers are never destroyed, you can create them all on Init
and set exec count to be the same as index of trigger in an array.

GetTriggerExecCount(Trigger) == i should always be true.

When you need to remove a trigger from place you do not swap it with the one on max[id] but only pass conditions
JASS:

if TriggerEvaluate(trig<i>) then
	call TriggerClearConditions(trig<i>)
        call TriggerAddCondition(trig<i>, Conditionz[max[id]])
        call TriggerClearConditions(trig[max[id]])
	set max[id]=max[id]-1
endif
</i></i></i>
 

Jesus4Lyf

Good Idea™
Flare>what exactly is different between this and key timers 1, and is it as easy to use?
Yes. Very, very easy to use. For you, and what you need to understand, it equates to this... Exactly the same as Key Timers 1 but with a significantly easier interface. If you want to compare with TT, then it's the same to use but you can specify period.

Basically, instead of calling the textmacro, you use function calls. See the KeyTimers2.w3x example map for details on similarities/differences. Should help. :D

Now that this system is established, I may start releasing some spells for it myself... :shades:

If people want to ask a request or two for different spells, I may give it a shot and post them as examples. :D


>preloading triggerExecCount
Preload as in call it on map init, or is there a call to make to preload the function for something (unfamiliar terminology)?

>GetTriggerExecCount(Trigger) == i should always be true.
In a perfect world. The whole point is to eliminate the array call. Of course, giving triggers unique integers would be fine, if only structs allowed you to specify their id... :banghead:

You have a good idea there, but I would just use your attachment method if I was going to involve arrays anyway. =/

I can't create the triggers on map init btw, because the system won't know what periods are in use or how many triggers to make.
 

Cohadar

master of fugue
Actually you can but never mind.
It is true that using attaching would be more sane.
 

Jesus4Lyf

Good Idea™
And more efficient for loading, which is what the whole point is - to exclude the array call and just use natives. :shades:

The real way to do it all is have the Add function return an integer (the trigger's unique id which means you'd never have to change the execcount again) which you use as the struct to attach things to, and you just forget all about using struct.create() and struct.destroy(). But that's terrible coding practise, even though it would work and be unbeatable in efficiency.

Edit instead of double post: New example spell created, demonstrating the full power of Key Timers 2: Sandman.
 

Flare

Stops copies me!
Staff member
got a question about using KT with unit groups. im trying to make a spell that knocks back units as a dummy unit encounters them so im gonna add them to a unit group and bla bla bla. if i pick every unit within the group, and do the actions like so

JASS:
//However I pick every unit within unit group
set i.pushunit=(GetUnit ())//that should be GetEnumUnit i think but not totally sure ^^
call Do&lt;insert something here&gt;
//dont have WE open and i forget where my WC disc is so everythings a little unknown


would that (under the assumption that it works with one unit) work so that every unit that should be pushed, will be pushed at the same time, or will it wait until the timer ends before moving the next unit?

also, if it didnt wait until the timer was finished, would the variable overlap within the timer loop, making units stop for no apparent reason?
 

Jesus4Lyf

Good Idea™
Just got back from holidays...

Sorry your code is a bit vague. I explained elsewhere how to to something to all units within a certain radius... I'd use that method:
JASS:
local group g=CreateGroup()
local unit t
call GroupEnumUnitsInRange(g,GetUnitX(unit),GetUnitY(unit),distance,null)
	loop
		set t=FirstOfGroup(g)
		exitwhen t==null
		call GroupRemoveUnit(g,t)
		if &lt;CONDITIONS INVOLVING T WHICH IS ENUM UNIT&gt; then
			&lt;DO STUFF TO T WHICH IS ENUM UNIT&gt;
		endif
	endloop
call DestroyGroup(g)
set g=null

Note that these groups aren't reusable as they must remove all units from the group as it is used. However, since I assume you'll pause the units that are sliding, and that they'll slide with the dummy unit (which is not needed, you can just store an x and y in a variable) that they will not leave the radius anyway, and so will be included every time it loops. Using ForGroup is generally a bad idea in my opinion. Sometimes it's the best way though... But I tend to use this instead. Hope that helps, if it doesn't, ask for further help... Sorry that I've been on holidays and stuff, chances are this is out of date for you anyway. :p
 

Hatebreeder

So many apples
Just got back from holidays...

Sorry your code is a bit vague. I explained elsewhere how to to something to all units withing a certain radius... I'd use that method:
JASS:
local group g=CreateGroup()
local unit t
call GroupEnumUnitsInRange(g,GetUnitX(unit),GetUnitY(unit),distance,null)
	loop
		set t=FirstOfGroup(g)
		exitwhen t==null
		call GroupRemoveUnit(g,t)
		if &lt;CONDITIONS INVOLVING T WHICH IS ENUM UNIT&gt; then
			&lt;DO STUFF TO T WHICH IS ENUM UNIT&gt;
		endif
	endloop
call DestroyGroup(g)
set g=null

Note that these groups aren't reusable as they must remove all units from the group as it is used. However, since I assume you'll pause the units that are sliding, and that they'll slide with the dummy unit (which is not needed, you can just store an x and y in a variable) that they will not leave the radius anyway, and so will be included every time it loops. Using ForGroup is generally a bad idea in my opinion. Sometimes it's the best way though... But I tend to use this instead. Hope that helps, if it doesn't, ask for further help... Sorry that I've been on holidays and stuff, chances are this is out of date for you anyway. :p
Actually, I use that method for Stuff like "IsUnitEnemy(...) == true" in an If then else statement in the loop.
Since (At least of my knowledge) there is no System, where I can pass though Data from one struct, to a non-timer, non-dialog, non-trigger function (In this case, some Condition Function).
 

0zaru

Learning vJASS ;)
Instead use a ForGroup call (Use a global variable,It must work if there are no waits (And you must not have waits since you use timers :p)). You can get a struct from a ForGroup callback with a get from GetTriggeringTrigger().
 

Jesus4Lyf

Good Idea™
... That's a really good point. You'll be able to load the struct from the ForGroup call just like from the timer trigger, using the GetTriggerExecCount thing. I still prefer using the FirstOfGroup loop over the ForGroup call though. It's just nicer in my opinion to keep everything in one chunk of code. More linear.
 

Jesus4Lyf

Good Idea™
I'd like to inform people of a not-so-important discovery.

Calling a function that returns a value from an array is FASTER than calling GetTriggerExecCount(GetTriggeringTrigger()).

That's right. It turns out my method was slower all along. I have updated KT2 accordingly. Additionally, I have done two other efficiency updates (the first of which can be applied to nearly all systems for efficiency gains). Instead of using local variables, use globals and pretend they're locals.

Bench tests have concluded that:

JASS:
local integer j=2

takes twice as long to execute as
JASS:
globals
integer J
endglobals
...
set J=2


Additionally, when reading the same value from an array 4 times, it is more efficient to store that value temporarily in a global, and refence that instead. If you read it 3 times, it is much the same, but slightly less efficient with the global (within 5% speed, off memory). If you read it 2 times, it is less efficient to store it first. I've applied this to optimize also.

KT2 is now significantly faster than it was before. If you apply the new version to Sharl and Sandman (keeping in mind to change GetExec(trig) thingie to KT_GetData()) then they don't lag at all. Which is amazing, imho. They're both full 3D MUI spells which micro manage between 40 and 400 pieces.

Anyway, KT2 Version 1.1 released. :)
 

Sim

Forum Administrator
Staff member
Wow, that is impressive Jesus. :)

Ungraveyarded. I'm using keytimers2 in my new spell and must say it is really efficient. Setting your own period is really a great feature, along with this system's efficiency brings it pretty high on my useful systems list. This system is really neat.

Plus, I was using the old version...

Any comments before I move this into the systems section?
 

Sim

Forum Administrator
Staff member
.

Any comments before I move this into the systems section?
As I said, this timer system is really neat.

> bench tested them, explained how they work, and written a report on them. Here it is:

That's a first! And you might want to write a tutorial on that, too. ;)

Impressive work. Definitely.

Approved.

EDIT: merged posts.
 

Jesus4Lyf

Good Idea™
Benchmarked! Timer Systems in Warcraft III.

Took a year (originally released Christmas, 2007) and went through the graveyard and back to get approved, but it's back and now comes with detailed documentation.

I've gone through the trouble of downloading a selection of timer systems, analysed how they work, bench tested them, explained how they work, and written a report on them. I sincerely recommend that everyone goes and takes a look at it. The documentation is on the second post on the first page.

Go to that post

Note by Daxtreme - Message to users replying in this thread: Please DO NOT reduce this thread into any kind of flamewar over benchtests. Thanks.

Better preventing than reacting!
 

emjlr3

Change can be a good thing
would like to see some benchmarks comparing TimerUtils, and perhaps HSAS or one of the other more popular attachment methods.
 

Jesus4Lyf

Good Idea™
Then benchmarks you will see.

I didn't bother bench testing the attaching method, for obvious reasons.
But in case those reasons aren't obvious, it's basically because it's insignificant compared to how fast the loop executes (100 to 1 kind of thing). More on the theory of that in my report; Timer Systems in Warcraft III.

The computer I tested them on had a reboot since the first tests, obviously, so I also re-benched KT2 for comparison, but even KT2's first result beats them all...

Anyway, using the same test as in my report (and I intend to update the report with these soon enough):

KT2 <3: ~32,000 executions per second.
TimerUtils Red: ~30,100 executions per second.
TimerUtils Blue: ~26,500 executions per second.
HSAS (used on a timer): ~24,800 executions per second.
I swear it's the fastest!: ~31,400 executions per second.

Ok. I want you all to note something. The "I swear it's the fastest!" test. That was me using:
JASS:
set FastFood[H2I(t)-0x100000]=Data

and
JASS:
local integer i=FastFood[H2I(GetExpiredTimer())-0x100000]


Key Timers 2 is faster. :nuts:
Key Timers 1 is in the vacinity of twice as fast.
Not to mention both are far, far more stable.
At this point in time, I can't imagine ever suggesting anyone use anything else. Except for 0.0 period timers.

There is a version 1.2 of KT2 coming some time, by the way. It won't improve the loop speed, just needs a little cleanup. :)

Edited: Version 1.01 of Timer Systems in Warcraft III has been released, including these results and their original test maps.

Edited again: Did another bench of TT, too. It averaged 31,900. Consistent with previous results. It's not just margin of error.
 
You'd better go an post this at wc3c.net, to increase popularity that is. ^^
Seems a decent system, though I have no idea how it would be faster than 0x100000 substraction since that is supposed to be the fastest...
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • tom_mai78101 tom_mai78101:
    Make sure you keep checking out my news..
    +2
  • Jesus4Lyf Jesus4Lyf:
    Man, I made this account 15 years ago? Wild. :)
  • Ghan Ghan:
    Seeing J4L is definitely a blast from the past.
  • Jesus4Lyf Jesus4Lyf:
    Oh hey Ghan! Long time. :)
    +1
  • jonas jonas:
    J4L! What has happened in your life
  • Jesus4Lyf Jesus4Lyf:
    Hmm, how to summarize... Moved to the USA and got married. Became a professional software engineer and solution lead. Learning Godot for game dev. :)
  • jonas jonas:
    So you are pursuing game dev as a hobby? What industry is your dayjob in?
  • jonas jonas:
    FAANG?
  • Jesus4Lyf Jesus4Lyf:
    Not quite FAANG, less pay for a less hours/stress. Yeah, game dev as a hobby.
  • jonas jonas:
    makes sense. Do we have a hobby game dev subforum to showcase some work?
  • Blackveiled Blackveiled:
    Happy Thursday
    +1
  • The Helper The Helper:
    Happy Thursday!
  • The Helper The Helper:
    TGIF!
  • The Helper The Helper:
    hey tom_mai please do not archive anymore news
  • Ghan Ghan:
    AMD Ryzen 7000 next week :D
    +1
  • The Helper The Helper:
    noice!
  • tom_mai78101 tom_mai78101:
    "hey tom_mai please do not archive anymore news" ----> Got it. What should we do with the "News Archive" subforum?
  • The Helper The Helper:
    I think leave it for real old news that cannot be sorted the reason we had it in the first place was a server issue that we do not have anymore. I don't want to get rid of the archive just not put anything in it for now until we figure it out more
  • The Helper The Helper:
    The side chat has nothing on the discord. it is not possible but the biggest thing on my wish list right now is a sidechat channel on the disord that hooks up to this...
  • Ghan Ghan:
    I've been selected for the Diablo IV beta.
    +1
  • Ghan Ghan:
    Woo!
    +1
  • The Helper The Helper:
    that is so cool
  • V-SNES V-SNES:
    Eh just noticed the new discord section on the side. Looks great!
    +1
  • Blackveiled Blackveiled:
    :( feels bad I can't ever get selected for any beta I sign up for. It's annoying as heck.
    +1

    The Helper Discord

    Members online

    No members online now.

    Affiliates

    Hive Workshop NUON Dome World Editor Tutorials

    Network Sponsors

    Apex Steel Pipe - Buys and sells Steel Pipe.
    Top