HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Marrying Triggers; Effective?

12-29-2003, 04:51 AM#16
weaaddar
Its not just for optimization, its all for organazation sake. Having tons of if blocks is just pretty ugly unless theres logic too it.
12-29-2003, 06:27 AM#17
Scarlet-Russian
1. a bunch of if statements will be the EXACT SAME THING
2. ELSE ifs will make it more optimized.
3. For some triggers, you might want to call a "Destroy Trigger" in the case that it will never be used arain (i.e. hero level up)
12-29-2003, 07:51 AM#18
Zechnophobe
I'm working, currently, on a project which I've done nothing but trigger work for oh, 15 - 20 hours of work time so far. I've been absolutely anal about how my code is commented, and looks. The system I'm using is actually just the inferstructure to how the campaign is going to run (How combats are initialized, set up, how are units sorted into a 'inventory' and status screen, etc). This way, when I start adding new methods, and working with my created infrustructure, I can quickly figure out how to use my own triggers. I also now have soo many variables, I mark each with two Capital letters at the start, declaring what kind of variable it is (I_UnitNum, S_UnitName, for example).

Example:
Quote:
Clockwise
Events
Player - Player 1 (Red) Presses the Left Arrow key
Conditions
Actions
-------- Shift the ClockWork Units ClockWise --------
Set U_ShiftCharacter = UA_StatusPCs[0]
For each (Integer A) from 1 to 11, do (Actions)
Loop - Actions
Set UA_StatusPCs[((Integer A) - 1)] = UA_StatusPCs[(Integer A)]
Set UA_StatusPCs[11] = U_ShiftCharacter
-------- If = Update Status Screen, then Pause Rotation --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
True Equal to True
Then - Actions
Trigger - Run StatusUpdate <gen> (checking conditions)
Trigger - Turn off (This trigger)
Trigger - Turn off CounterClockwise <gen>
Wait 1.00 seconds
Trigger - Turn on CounterClockwise <gen>
Trigger - Turn on (This trigger)
Else - Actions
Notice the True = True comment, and then a bunch of iterative steps. When this trigger is viewed in the trigger editor, you only see the IF, and the Comment above it, so you don't take 10 seconds looking through the code. Also makes tracking down the functions that 'update the status screen' easier to find.
12-29-2003, 03:27 PM#19
weaaddar
I should explain why I suggested such an arguably worthless optimization. I use to and still on occasion program C for a the ti-89 calculator.

The calculator has 12 mhz. Using the very useful semi-3d rendering engine the FAT engine nearly consumes around 7000k-8000k clocks, the os consumes it shares and then theres overhead for using a no-stub method to launch the program. (Theres a limit on the amount of memory the ti-89 allows to be launched directly, theres methods around that).
All in all, such a meaningless optimization on a comp will save maybe maybe 40 or 50 clocks at most on a huge if block. That doesn't sound like much, but on a system with only 12,000k clocks of which at most 4000k are yours to do as you please, this makes or breaks your code.

Anyway its just more stylistically correct.
12-29-2003, 03:38 PM#20
Extrarius
You're off by a factor of 1000, you get at least 4,000,000 ticks per second (assuming the os uses 66% of the ticks, but I'd really doubt it because on my 92+ which has almost an identical OS, it is not a multitasking OS - there are certain things that call interrupts, like key presses and a time tick a few times a second, but you can remap the interrupts ot just return if you don't like them).
I've done some programming for the TI-92+ (before there was a c compiler for it) and I never had any problems with not enough clock cycles. Unless you're making a true 3D program or doing number crunching you shouldn't have a problem with speed. Graphics and the like take a lot less time when you only have 1/2 bit color and only a few thousand pixels.
If you want a real challenge, try programming the TI-82 =-)
12-29-2003, 07:25 PM#21
weaaddar
sorry I forgot the Ks on my original post.

The FAT3d engine is quite a memory hog as well but I don't think I should mention that. Anyway it was quite hard as I was trying to throw an RPG layer on top of the already complex rendering engine.
12-29-2003, 10:50 PM#22
jmoritz
I tried making a GBA pacman with a smart AI. GFX is fast enough, but even simple A* on a 30x30 field totally ruined the game because of lag. GBA is just a few MHz and it had to do the entire algorithm 4 times in 1/30 of a second :( I had to optimize to death to make it playable.

So yeah, the optimization is a valid one, but not on today's PCs :)

Note: nesting IFs doesn't always make it easier to read.
Code:
if (A) {
  if (B) {
    doShit();
  }
  else
    if (C) {
      doOther();
    }
  }
}
else {
  if (!C) {
    doOthercrap();
  }
}

if (A and B) doShift();
if (A and !B and C) doOther();
if (!A and !C) doOtherCrap();
12-29-2003, 11:56 PM#23
Grater
Some people raise very valid points about optimzation vs organazation.

Another very valid point is sometimes there is often an entirely better way to do something, that could run a hundred times faster than doing some tedious optimization like marrying a whole bunch of triggers with chained if/then/else.

Generally this will involve arrays, for example I wrote some highly effecient creep respawn triggers, most triggers work like this:
E - Unit dies
A - Wait a while
A - Check for nearby enemy units
A - Revive unit
A - Repeat the above.

What I did was entirely eliminate the Unit dies event, instead I had a periodic running every couple of seconds that would check each creep camp in turn, it would only do one check for enemy units per entire creep camp (instead of one per dead creep), and if no enemies are found it revives all the dead creeps at the camp, it even figured out the creep camps on the fly, not needing any regions at all.

The fundamental method was using an array of creep units (and an array of locations, and types), and the "IsAlive" condiion, altough obviously the full trigger was far more complex because of the creep camp stuff.

Using such a superier system probably results in my triggers running in a hundreth of the time of typical respawn triggers, while also being more powerful, allowing automatic reviving select units owned by any player and didn't even consider reviving summoned units. Such performance and usability gains would not have been possible by simply marrying a creep dies trigger with the other unit dies triggers.
12-30-2003, 12:55 AM#24
weaaddar
In memory case...Technically with less triggers it easier to clean the cache of them with using the DestroyTrigger() jass command. (it for some reason clears the hell out of memory). Remember to avoid commands which return handles as they are generally innately bugged and lead to that massive after game lag where you sit there waiting till hell freezes over.

jmoritz:

Well in your case probably the later is more readable but with only so few conditions does it so. I had to write a java program recently where I had to determine the place of over a 100 racers each being randomly incremented and display a text message displaying there current position against everyone elses at the end of the race. (I.e. a query for racer 55 would yield this result 1. R55 2. R27 3.R43... while a query for racer 27 would yield 2.R27 1.R55 3.R43 ... and a query for racer 50 would yield 50. R50 1.R55 2.R27...) without nested if and for loops I probably would of shot myself and dropped the course.
12-30-2003, 03:38 AM#25
th15
Quote:
Originally posted by weaaddar
Remember to avoid commands which return handles as they are generally innately bugged and lead to that massive after game lag where you sit there waiting till hell freezes over.


Please explain to me what a handle is, i havent a clue. My problem with my map is that it IS taking forever to unload after the game has ended. I have a 0.5s periodic trigger moving 9 turrets to 10 players and ive tried to reduce lag with the temploc/destroy temploc method but its only partially solved the problem.
12-30-2003, 03:44 AM#26
weaaddar
Well I'll correct that to say Non native function which return handle types, you have to be really sure.
Local handles are not destroyed at the destruction of a run of a trigger.

Anything in common.j is fair game to use. Blizzard.j is where you have to fear.
A handle is basically anything that isn't an integer, real, boolean, or a string, or code (function/trigger)
Objects, widgets, dialogs, leaderboards, regions, rects, multiboards, quests, cameras...
All handles.

check the jass vualt, they had some functions for moving units to regions if I remember correctly.

The problem is your trigger keeps building up a memory leak at a very fast pace. Blizzard emergency garbage collector as I've nicked it runs under two circumstances. The game is about to crash due to memory overload (you've seen it in mplayer the game gets really laggy for no real reason then all of sudden dies down) and after the game finishes. I imagine if you let your map run long enough you'll get the former condition to get the garbage collector to run but thats probably not a good answer.
12-30-2003, 05:20 AM#27
th15
Soo you are saying that any function that picks a unit group or returns a unit variable causes some mem leak? I learnt a little programming but im not THAT familiar with the architecture :(

My trigger references an 2d array of 9x10 turrets for each player that is still active then moves the turret to the position of the player's hero (another array).
12-31-2003, 01:22 AM#28
RicFaith
very interesting answers here, so I thought I'd pose some questions?

1) Which is more effective:

If (condition)
do blah1
else
- If (condition2)
- do blah2
- else
- - If (condition3)
- - do blah3
:
:
:

or

If (condition)
do blah1
skip remaining actions
If (condition2)
do blah2
skip remaining actions
If (condition3)
do blah3
skip remaining actions
:
:
:

or should I just convert all to JASS and fumble my way through
If (condition)
:
elseif (condition)
:
elseif (condition)
:

(There is an elseif command in JASS right?)

---

2) Qn on the array method.

So you have a global trigger array that stores all the different triggers and is called based on the triggering event? or is a local array better? and if I use a local array, doesn't it get reassigned everytime the function/trigger is called? or is there a way to put it in the trigger, but not in the function. Or do I put it in the Custom Script section?

---

Let's assume that I'm willing to sacrifice some readability to improve speed and reduce lag. I'd rather not venture into Jass cuz my brother who is doing half the work is terribly new to any kind of programming, but I would force him to start learning the simple stuff if it were a big boost to the end result.
12-31-2003, 01:46 AM#29
th15
I've got another question to add. I use alot of math- random number to add a little vriance to where my turrets are moved. this prevents them from overlapping 100% and that way it actually looks like you have more than 1 gun. I know from my java experience that random number generation and arithmetic require quite little CPU power but im just grasping for straws here, my map takes 2 minutes of black screen to close on my comp. My friends, they have to force wc3 to close.

If anyone really good at JASS is willling to look through my map and optimize the code, i'd be willing to give points and would be very appreciative.
12-31-2003, 02:02 AM#30
Grater
I'll take a shot at it, my e-mail is [email protected].

Random numbers shouldn't cause lag, but moving the locations around definitely could.