HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Blaze

10-04-2007, 01:10 AM#1
emjlr3
Blaze v1.1

by emjlr3


Explanations:
  • What it does - upon casting the ability, conjures X flaming orbs, which circle the caster, and upon reaching their ascent, careen forth at random targets in the area, exploding upon impact, dealing damage to the unlucky foe.
  • Why I made it - I made it for a tower contest, and actually managed to place, which was kind of neat.
  • Why you should try it - I think it is a pretty neat ability. Makes use of vJASS to move lots of projectiles around, and you may actually find it useful, if not to use in a map, possibly to learn from.
  • Concerns - there is a lot of stuff flying about all at once, so it could get laggy with 10 or less firing at the same time on low end computers. I believe I have updated the trigger to be completely self sufficient, however if I missed something, let me know. Also, do not mind all the other triggers in the map, this was the test map I used for the ability, and I think it is an easy way to demo the spell as it is, simply look in the Spells folder for the abilities trigger.
  • Etc. - thanks to Vexorian, PipeDream, Zoxc, PitzerMike and all those who made the JASS NewGen Pack possible.


Expand Spell code:

Updates:
  • v1.1 -fixed some spelling/grammar errors in my documentation and explanations
    some functions renamed
    added a public global trigger named Blaze_Trigger which is now used at the abilities global trigger
    ported to an active instant cast ability
    updated the Blaze_data1 arrays to a size so it works properly
    changed setunitposition to setunitx/y
    reduced groupenum call from max missiles to 1 when grabbing targets for the missiles
    removed getunitx/y calls for each missile and during every twirl interval, now done only once
    added many configuration parameters
    removed all unneeded systems from map

Thoughts? Suggestions? Concerns? Mal contempt?
Attached Images
File type: jpghreshers.jpg (70.4 KB)
Attached Files
File type: w3xemjlr3 - Blaze v1.1.w3x (93.0 KB)
10-04-2007, 02:24 AM#3
Rising_Dusk
My first concern is the upper limit of how many of these can be out before lag becomes noticeable. No matter how it is made, enough of these is going to kill FPS.

EDIT:
And for what it's worth, it does look well-presented and cool.
10-04-2007, 03:02 AM#4
Vexorian
could we please begin to be modular when making spells? You are just making things harder if every spell has to use its own gamecache, there is a gamecache file limit, you know... at least don't call the variable cscache...

It is great you are using an scope, but you are not taking full advantage of it. When you use an scope you can make the code totally multi instanceable without any effort by just changing the scope name after duplicating the code, in your case there's some things that are redundant although they should work correctly.

gg_trg_Blaze is a variable outside the scope, and you don't really need it to be a global you could simply use a local trigger variable to declare the events...

Things like _Blaze_ inside a private function's name are pretty redundant as well.

I2S(H2I(tower))+"Blaze" : SCOPE_PRIVATE+I2S(H2I(tower)) makes a lot more sense.

I seriously think you can/should get rid of gamecache in this one, it is just adding a lot of code bloat, the problem with the lack of modularization and the gamecache limit, and if I am not mistaking it is all for a single tag? There are plenty of things you can fix this, the easiest would be to use 3 arrays and just perform substraction, but you can also use a trie or hash table...
10-04-2007, 04:07 AM#5
emjlr3
Quote:
Originally Posted by Rising_Dusk
My first concern is the upper limit of how many of these can be out before lag becomes noticeable. No matter how it is made, enough of these is going to kill FPS.

EDIT:
And for what it's worth, it does look well-presented and cool.

This is very true, as I mentioned. I have a very fast computer, and at around 15 or so I start to feel the heat pretty good. Unless someone has some big idea of how to make this incredibly more optimized, I don't see a work around, however, aside from completely remaking it, or changing the spell itself, I am up for suggestions.

Quote:
Originally Posted by Vexorian
could we please begin to be modular when making spells? You are just making things harder if every spell has to use its own gamecache, there is a gamecache file limit, you know... at least don't call the variable cscache...

It is great you are using an scope, but you are not taking full advantage of it. When you use an scope you can make the code totally multi instanceable without any effort by just changing the scope name after duplicating the code, in your case there's some things that are redundant although they should work correctly.

gg_trg_Blaze is a variable outside the scope, and you don't really need it to be a global you could simply use a local trigger variable to declare the events...

Things like _Blaze_ inside a private function's name are pretty redundant as well.

I2S(H2I(tower))+"Blaze" : SCOPE_PRIVATE+I2S(H2I(tower)) makes a lot more sense.

I seriously think you can/should get rid of gamecache in this one, it is just adding a lot of code bloat, the problem with the lack of modularization and the gamecache limit, and if I am not mistaking it is all for a single tag? There are plenty of things you can fix this, the easiest would be to use 3 arrays and just perform substraction, but you can also use a trie or hash table...

what is wrong with the name cscache, its private, so it'll be called Blaze something or other. Unless you have some neat idea for a built in game cache variable in NewGen, I do not see away around it other then requiring your CSCache system.

I left the global trigger in case for some reason anyone ever wanted to access it, to say, turn off the ability, or turn it on, or something along those lines, I can't see how it would hurt, and I do realize I do no longer need a case sensitive prefix built into function names when in a scope ( and I usually do not, not really sure why I do here actually), though again, who is it hurting?

@I2S(H2I(tower))+"Blaze" : SCOPE_PRIVATE+I2S(H2I(tower)) makes a lot more sense.
>not real sure at all what that is supposed to mean....

as for removing GC, I do not think I am versed in "subtraction", nor in tables or trees....care to point me in the right direction, that I may be learned? As far as setting a cooldown, aside from using the units userdata, I wasn't sure how else to achieve the needed effect
10-04-2007, 04:40 AM#6
Vexorian
Quote:
I left the global trigger in case for some reason anyone ever wanted to access it, to say, turn off the ability, or turn it on, or something along those lines, I can't see how it would hurt, and I do realize I do no longer need a case sensitive prefix built into function names when in a scope ( and I usually do not, not really sure why I do here actually), though again, who is it hurting?

It is unlikely they would ever do that, but if so, make the trigger public a.k,a add the scope prefix, these gg things just make the spell a little more complicated to implement if you don't use the trigger editor for your scripts...

--
use cscache, make your own library for gamecache that is outside the spell's code, something like that, modularizing stuff is healthy. It is not good that a single spell comes with its own gamecache system.

The deal is that since it is scope based, you are few steps away of having a super template, but these little details are not making it possible, so I think it is not an actual problem but more of seeing the full potential of scopes not getting exploited.

subtraction: if (cooldown[H2I(u)-0x10000]) then

Or you can use multiple arrays.
10-04-2007, 06:34 AM#7
cohadar
using attachments on units, ccc.
10-04-2007, 11:11 AM#8
Gorman
a found something interesting, when it fires if the initial target is killed then the fireballs will find another target, a few times ive had fireballs racing around the map looking for targets, only to have that target destroyed, and have to find a new target, this all happening well outside the towers usual range, you may want to have a look at this...
10-04-2007, 11:29 AM#9
Anitarf
First of all, this is an eye candy spell. The actual gameplay effect it has can be summed up into "damage 5 random units in an area", which isn't particularly impressive. As such, I'm not entirely sure it qualifies for the spell resource section (then again, not all eye candy spells are banned, only "cinematic" ones).

I find it very lacking in the calibration department. You can't choose the number of projectiles, duration of the rotation, starting&end radius&height, turn speed, targeting options, etc... Furthermore, you can't make it a multi-level ability, and the falling speed of the projectile is completely arbitrarily chosen (what if it targets an air unit?)

It also needs to be optimized more. Sure, it's already easy on gamecache thanks to structs but if it's causing a drop in my framerate then it's not optimized enough. You have to move to other things besides reducing game cache use, like reducing the number of function calls by inlining stuff and not doing silly stuff like getting the x and y of the tower every time instead of storing them to a variable. Perhaps, once the code is inlined, having a seperate struct for each projectile from the start might be more efficient.

It's not smart to use the attack event. I could spam stop and get triple the attack speed out of my towers. Sure, you could increase the triggered cooldown to counter that, but then you're preventing the use of any attack speed increasing abilities which kind of defeats the purpose of using the attack event, you could just use a periodic event instead. You could also use the damage event, but we all know how annoying that is. This would work much better as a instant cast spell, or maybe a channeling one.

Also, you need to specify which of the systems that are in the map does your spell need.

Doesn't a struct array member of size [5] go from 0 to 4?

Gorman: if you looked at the code, you would see that's expected behaviour.
10-04-2007, 11:40 AM#10
Tide-Arc Ephemera
Just curious, but is it lag on the graphical or technical end? It really seems (in my opinion) to be on the graphical end, with a model like this that spews out lots of particles.
10-04-2007, 12:53 PM#11
Vexorian
Quote:
Doesn't a struct array member of size [5] go from 0 to 4?

Yes.

I think I am going to have to wrap the array member accesses on debug mode to report access violations...

Quote:
Just curious, but is it lag on the graphical or technical end? It really seems (in my opinion) to be on the graphical end, with a model like this that spews out lots of particles.
You know, there is an easy way to verify that, replace the models with ""
10-04-2007, 01:06 PM#12
blu_da_noob
The current lag is graphical to a large extent, but there are still many things you can improve on it. Using SetUnitX/Y for example. And when the missiles reach the top of the spiral, you do a full group enum for each individual one, whereas you only actually need to do one for the whole group. And using so many function calls (ie methods) probably doesn't help.
10-04-2007, 02:24 PM#13
emjlr3
Quote:
Originally Posted by cohadar
using attachments on units, ccc.

its not really on the unit, it is completely MUI, and there is no leak....what is the big deal?
in any case, as stated earlier, I didn't know of another way to do it, now I do

Quote:
Originally Posted by Gorman
a found something interesting, when it fires if the initial target is killed then the fireballs will find another target, a few times ive had fireballs racing around the map looking for targets, only to have that target destroyed, and have to find a new target, this all happening well outside the towers usual range, you may want to have a look at this...

you can specify the distance the missiles can look for new targets, and there is no limit to the times this can be done, if a missile finds 5 different targets, which all die, it could end up pretty far away, considering the "look" distance is currently 1000. or so

Quote:
Originally Posted by anitarf
First of all, this is an eye candy spell. The actual gameplay effect it has can be summed up into "damage 5 random units in an area", which isn't particularly impressive. As such, I'm not entirely sure it qualifies for the spell resource section (then again, not all eye candy spells are banned, only "cinematic" ones).

I find it very lacking in the calibration department. You can't choose the number of projectiles, duration of the rotation, starting&end radius&height, turn speed, targeting options, etc... Furthermore, you can't make it a multi-level ability, and the falling speed of the projectile is completely arbitrarily chosen (what if it targets an air unit?)

It also needs to be optimized more. Sure, it's already easy on gamecache thanks to structs but if it's causing a drop in my framerate then it's not optimized enough. You have to move to other things besides reducing game cache use, like reducing the number of function calls by inlining stuff and not doing silly stuff like getting the x and y of the tower every time instead of storing them to a variable. Perhaps, once the code is inlined, having a seperate struct for each projectile from the start might be more efficient.

It's not smart to use the attack event. I could spam stop and get triple the attack speed out of my towers. Sure, you could increase the triggered cooldown to counter that, but then you're preventing the use of any attack speed increasing abilities which kind of defeats the purpose of using the attack event, you could just use a periodic event instead. You could also use the damage event, but we all know how annoying that is. This would work much better as a instant cast spell, or maybe a channeling one.

Also, you need to specify which of the systems that are in the map does your spell need.

Doesn't a struct array member of size [5] go from 0 to 4?

not a fan of eyecandy?

it is very lacking in the calibration department, I agree, it originally was not made to be completely calibrated, just to be used as is, with some general needed changes

you cannot really make the assumption that because it is dropping your fps it is not optimized enough. every physics system, no matter how well written, is going to lag with 100 or 200 projectiles on the screen, or there abouts
and what is inling??

the "cooldown" is basically just there to stop being able to trigegr this over and over really fast, the cooldown should probably be set as the minimal attack cd this unit could have
I do agree it would be better as an active ability, but then, that kind of was not the point of the spell in the first place, I made iit as a pretty attack replacement

as for what system are needed, I was under the impression that my implementation instruction covered that, as did the note that
"Also, do not mind all the other triggers in the map, this was the test map I used for the ability, and I think it is an easy way to demo the spell as it is, simply look in the Spells folder for the abilities trigger."

Quote:
Originally Posted by Vexorian
Yes.

I think I am going to have to wrap the array member accesses on debug mode to report access violations...

hrmm, so declaring array[5] only gives you 0-4? then how is it that I used 1-5 w/o any problems I wonder?
Quote:
Originally Posted by blu_da_noob
The current lag is graphical to a large extent, but there are still many things you can improve on it. Using SetUnitX/Y for example. And when the missiles reach the top of the spiral, you do a full group enum for each individual one, whereas you only actually need to do one for the whole group. And using so many function calls (ie methods) probably doesn't help.

is setx/y really that much faster then setunitposition?
considering I do not run a path ability detection, there is probably always that risk the projectile could fly out of bounds...
and what is this about methods = bad? I always thought they were encourage to keep things straight, or thereabouts

In any case, come next week sometime, unless I manage to find some time before then, I will go about trying to make some changes on this
possibly, add more config., change some of the optimization things people have suggested, as well as possibly how it fires(from on attack to active cast)
10-04-2007, 02:30 PM#14
Vexorian
Quote:
hrmm, so declaring array[5] only gives you 0-4? then how is it that I used 1-5 w/o any problems I wonder?

If you always used 1-5, then you will only have problems if by some way you get to the last index. the 1638th instance would try to access index 8191 when you use 5, and then it would cause a little bug when loading the map. Not a big bug, but it is better to use the indexes correctly, I think.
10-04-2007, 04:29 PM#15
blu_da_noob
Quote:
you cannot really make the assumption that because it is dropping your fps it is not optimized enough. every physics system, no matter how well written, is going to lag with 100 or 200 projectiles on the screen, or there abouts
and what is inling??

Except this is lagging at 50 projectiles. Inlining is putting all the code from a function into the script in place of the function call.

Quote:
is setx/y really that much faster then setunitposition?
considering I do not run a path ability detection, there is probably always that risk the projectile could fly out of bounds...
and what is this about methods = bad? I always thought they were encourage to keep things straight, or thereabouts

Yes SetUnitX/Y is much faster than SetUnitPosition (precisely because it doesn't do the pathing checks etc). If the missile is flying after the unit, I don't see how it could go out of map bounds (it would have to target a unit that is out of map bounds). But yes it is generally a good idea to put the check in just in case something goes wrong.

Methods like you are using them aren't bad outside of wc3. However, function calls are very slow in jass, so those extra 5 function calls per object add up.