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

Wurst Missile System

Status
Not open for further replies.
Level 5
Joined
Mar 5, 2015
Messages
135
Just curious if anyone has created a missile system for Wurst yet, which is open for public use? Otherwise I would attempt to make one, since it seems like a pretty useful tool for quite a few maps. :)
 
Level 5
Joined
Mar 5, 2015
Messages
135
So I decided to work on this myself, as I thought it might be good practice. The project will be public on GitHub here :)

@mods should I keep the thread open for development updates or should I move it out somewhere it?
 
Level 2
Joined
Dec 16, 2011
Messages
12
Not sure how helpful this will be but I was looking through the Wurst showcase repos and Gold Rush has some missile code.

WurstScript • Showcase

HannesHaglund/Gold-Rush

If I remember correctly the game had fire-in-a-line missiles to swap places with target unit or knockback in an aoe.
It was pretty neat that they separated the concept of the collision detection (they called it Sensors) with the actual projectile.
 
Level 5
Joined
Mar 5, 2015
Messages
135
Not sure how helpful this will be but I was looking through the Wurst showcase repos and Gold Rush has some missile code.

WurstScript • Showcase

HannesHaglund/Gold-Rush

If I remember correctly the game had fire-in-a-line missiles to swap places with target unit or knockback in an aoe.
It was pretty neat that they separated the concept of the collision detection (they called it Sensors) with the actual projectile.

Dude, it's super cool that you looked that through - didn't think of that mysef :D I'll try to take a look at the system, and see if there is anything I can use. It seems though, that his are line-missile (as you mention), but I want to develop a system which can handle all types of missiles.

Like the idea of sensors, just not sure if it's a good idea for efficiency
 
Level 5
Joined
Mar 5, 2015
Messages
135
Level 2
Joined
Jan 31, 2019
Messages
27
Yeah. I didnt know how the arc formula worked with original projectile so the gravity causes the same effect. The higher the gravity the higher the arc the projectile has to make to reach target before hitting ground, basically. And 0 means no arc.
 
Level 5
Joined
Mar 5, 2015
Messages
135
Yeah. I didnt know how the arc formula worked with original projectile so the gravity causes the same effect. The higher the gravity the higher the arc the projectile has to make to reach target before hitting ground, basically. And 0 means no arc.

Right, that's good to know ;)

With my own system, I'm trying to implement an adjustable arc measured in radians. It should be possible, and not that hard. I think I have the idea down, I just can't get the calculations to be correct :D
 
Level 2
Joined
Jan 31, 2019
Messages
27
In a sense that would not be realistic for the flight path though. If you you mean the launch angle would be the same regardless of distance.
But if you anyways need say, the projectile to reach a certain height, you will need to adjust the gravity based on the distance and horizontal speed. There is a simple formula in wikipedia for maximum height reached by a projectile Projectile motion - Wikipedia
 
Level 5
Joined
Mar 5, 2015
Messages
135
In a sense that would not be realistic for the flight path though. If you you mean the launch angle would be the same regardless of distance.

That's what I mean, and theoretically it whould be possible, as you would instead adjust the vertical velocity of the missile. My tests have found, that that seems to be how the original wc3 missiles are calculated.

But if you anyways need say, the projectile to reach a certain height, you will need to adjust the gravity based on the distance and horizontal speed. There is a simple formula in wikipedia for maximum height reached by a projectile Projectile motion - Wikipedia

You shouldn't have to tweak the gravity as far as I know. And as I mentioned above, the height of the missile is not determined by the horizontal distance, but rather by the vertical velocity, the gravity and the angle at which the projectile is fired. ;)
Been messing around with a few of the formulas on that wiki page as well :D
 
Level 2
Joined
Jan 31, 2019
Messages
27
Oh, right. If you want to keep the angle same you got to adjust the force at which the missile is fired instead. I just dont see how that would make sense with the homing component, which mystically gives the missile force to reach its target even if it moves away. Basically how my class works, is it calculates the required vertical speed on every update so if the target position changes it adapts the flight path like wc3 projectiles do.
Code:
//Update vertical speed for appropriate flight arc
let flightTime = distance2D / this.groundSpeed
real heightDifference = (this.targetPos - missileFx.getPos3()).z
this.verticalSpeed = (heightDifference / flightTime) - (0.5 * this.gravity * flightTime)
 
Level 2
Joined
Jan 31, 2019
Messages
27
However the calculations for required launch angle to reach a certain point is quite complex and only necessary if you want completely physics driven projectiles. And with a long enough distanc the projectile cannot even reach the target, so you cant just give it a point and tell it to fire there, since the force might not be high enough.

When you think how my system would work if it was a cannon firing, it would increase the angle & firing force so that the horizontal distance stays the same while still reaching the target point.
 
Level 5
Joined
Mar 5, 2015
Messages
135
Oh, right. If you want to keep the angle same you got to adjust the force at which the missile is fired instead. I just dont see how that would make sense with the homing component, which mystically gives the missile force to reach its target even if it moves away. Basically how my class works, is it calculates the required vertical speed on every update so if the target position changes it adapts the flight path like wc3 projectiles do.
Code:
//Update vertical speed for appropriate flight arc
let flightTime = distance2D / this.groundSpeed
real heightDifference = (this.targetPos - missileFx.getPos3()).z
this.verticalSpeed = (heightDifference / flightTime) - (0.5 * this.gravity * flightTime)

Right, you might be on to something with that homing component - not my focus at the moment :D But I suppose that should be able to be calculated the same way. Whether you adjust the "arc" of the missile in flight or the vertical velocity should be the same.

... On a side note: I actually tested the original wc3 missiles, and they don't home as smoothly as your solution at all ;) Rather, they just abrutly stop their smooth curve and instead just aim directly for the target in a linear path - it looks quite ridiculous.
 
Level 2
Joined
Jan 31, 2019
Messages
27
What is the application you are going for here exactly? I can hopefully help you as long as I understand what is the end goal of how you need your projectiles to work.
 
Level 5
Joined
Mar 5, 2015
Messages
135
Well, I don't need anything that works better than your solution, tbh ;) Now it's more of a challenge for myself to create such a system. But the primary hurdle atm is to figure out how to calculate the correct initial vertical velocity, when giving the parameters: distance, angle, and horizontal speed
 
Level 2
Joined
Jan 31, 2019
Messages
27
I believe
Vertical launch speed = tan(angle) * horizontal launch speed

However, if distance and horizontal speed and angle are a given, the flight path is basically set for a given gravity, therefore you must adjust the gravity to reach the target.
 
Level 5
Joined
Mar 5, 2015
Messages
135
I believe
Vertical launch speed = tan(angle) * horizontal launch speed

However, if distance and horizontal speed and angle are a given, the flight path is basically set for a given gravity, therefore you must adjust the gravity to reach the target.

The gravity or the vertical velocity ;)

Haven't stumpled on that formular though - that would make my life so much easier.
 
Level 2
Joined
Jan 31, 2019
Messages
27
The gravity or the vertical velocity ;)

Haven't stumpled on that formular though - that would make my life so much easier.

Thats simply not correct. The vertical velocity is only adjustable through firing angle, which you said was a given parameter. If you instead increase the initial total velocity ("cannon propulsion force") it will also increase the horizontal velocity unless you also change the angle.
 
Last edited:
Level 5
Joined
Mar 5, 2015
Messages
135
Thats simply not correct. The vertical velocity is only adjustable through firing angle, which you said was a given parameter. If you instead increase the initial total velocity ("cannon propulsion force") it will also increase the horizontal velocity unless you also change the angle.

Right, I might have said something wrong here. I agree with this:

However, if distance and horizontal speed and angle are a given, the flight path is basically set for a given gravity, therefore you must adjust the gravity to reach the target.

The flight path should indeed be set when given those parameters - that's the idea ;) The difference from your system to this, is that this takes the firing angle as a parameter instead of gravity.

Why I need the vertical velocity is for calculations purposes. And knowing the firing angle, the horizontal distance and velocity, I should be able to calculate it.
 
Level 2
Joined
Jan 31, 2019
Messages
27
Right, I might have said something wrong here. I agree with this:

The flight path should indeed be set when given those parameters - that's the idea ;) The difference from your system to this, is that this takes the firing angle as a parameter instead of gravity.

Why I need the vertical velocity is for calculations purposes. And knowing the firing angle, the horizontal distance and velocity, I should be able to calculate it.

If you know the angle and either the horizontal velocity or the total firing velocity, you get the vertical speed by:

Vertical launch speed = tan(angle) * horizontal launch speed

or

Vertical launch speed = sin(angle) * total launch speed

However, if you have a given firing velocity, your projectile might not even be able to reach a point that you want to reach. Also you cannot give firing angle, total distance to target and horizontal speed as parameters, since two of those being given means the third one is a given as well.
 
Level 5
Joined
Mar 5, 2015
Messages
135
That's exactly what I want ;) I have tried this:

Vertical launch speed = tan(angle) * horizontal launch speed

... But I can't seem to get it to work - probably something wrong with my other calculations. Have to try and find a fix for that.
 
Level 5
Joined
Mar 5, 2015
Messages
135
But it sure does create a nice arc, and is muuuuuch simpler than the solution I had to begin with, so this is really nice!
 
Level 2
Joined
Jan 31, 2019
Messages
27
If you know the angle and either the horizontal velocity or the total firing velocity, you get the vertical speed by:

Vertical launch speed = tan(angle) * horizontal launch speed

or

Vertical launch speed = sin(angle) * total launch speed

However, if you have a given firing velocity, your projectile might not even be able to reach a point that you want to reach. Also you cannot give firing angle, total distance to target and horizontal speed as parameters, since two of those being given means the third one is a given as well.

That's exactly what I want ;) I have tried this:



... But I can't seem to get it to work - probably something wrong with my other calculations. Have to try and find a fix for that.

I might be able to help if you if you share your code. Basically if you want your missiles to work so that they always launch at a constant total velocity, but at a different launch angle, you have to calculate the required launch angle like this:

ZyPPc1z.png

Source: Projectile motion - Wikipedia
 
Level 5
Joined
Mar 5, 2015
Messages
135
I might be able to help if you if you share your code. Basically if you want your missiles to work so that they always launch at a constant total velocity, but at a different launch angle, you have to calculate the required launch angle like this:

ZyPPc1z.png

Source: Projectile motion - Wikipedia

Alright, scratch what I've said - I have to bite the dust here. The pieces fall into place now. I see what you mean, that if I have a set horizontal speed and angle, the vertical speed will only have one possible outcome. Aaand the only way to adjust the distance, is to adjust the gravity (sorry for taking so long - just had to see it in practice).
And of course, I can still make it the way I want, such that I give those parameters, but what I have to worry about is not as much the vertical velocity as the gravity. So I have to calculate the appropriate gravity in order for it to go the distance that I want :D Enlightnement ftw
 
Level 5
Joined
Mar 5, 2015
Messages
135
This also makes me realize propably how they calculate the firing angle for with original wc3 projectiles. The "arc" setting probably sets the relation between the x-velocity and the y-velocity, such the the VelY = VelX * arc * someArcConstant (someArcConstant seems like its 2). Thus it will never be able to exceed a firing angle that is directly upwards nor negative or backwards. It also explains why the missiles go so fast when you set the arc to something high, like 5.
 
Level 2
Joined
Jan 31, 2019
Messages
27
This also makes me realize propably how they calculate the firing angle for with original wc3 projectiles. The "arc" setting probably sets the relation between the x-velocity and the y-velocity, such the the VelY = VelX * arc * someArcConstant (someArcConstant seems like its 2). Thus it will never be able to exceed a firing angle that is directly upwards nor negative or backwards. It also explains why the missiles go so fast when you set the arc to something high, like 5.

If you increase arc, does it take a longer time to hit the target even when distance stays the same?
If it stays the same, it probably works similarly to my system where the horizontal speed stays the same, and only vertical speed is increased (and the gravity, since otherwise increasing the vertical speed would increase distance).
If the time to hit target changes, the arc value is probably the value of tan(angle) and the vertical and horizontal speeds are just calculated with that ange, and then the gravity is reduced to a point where the projectile flies long enough to reach the desired distance.
 
Level 5
Joined
Mar 5, 2015
Messages
135
If you increase arc, does it take a longer time to hit the target even when distance stays the same?
If it stays the same, it probably works similarly to my system where the horizontal speed stays the same, and only vertical speed is increased (and the gravity, since otherwise increasing the vertical speed would increase distance).
If the time to hit target changes, the arc value is probably the value of tan(angle) and the vertical and horizontal speeds are just calculated with that ange, and then the gravity is reduced to a point where the projectile flies long enough to reach the desired distance.

From what I've found the projectile speed is the horizontal speed, so exactly the same as yours ;)
 
Level 2
Joined
Jan 31, 2019
Messages
27
Allright, in that case, if you want to modify my class to use an arc constant like WC3, you just replace the gravity parameter with an arc parameter that accepts values between 0-0.9999, calculate tan(arc * pi/2) * horizontal speed to get vertical speed, and then solve for gravity required to have the appropriate height after time = distance / horizontal speed

Code:
gravity = (2 / time) * (heightDifference / time - verticalSpeed)
 
Last edited:
Level 5
Joined
Mar 5, 2015
Messages
135
Allright, in that case, if you want to modify my class to use an arc constant like WC3, you just replace the gravity parameter with an arc parameter that accepts values between 0-0.9999, calculate tan(arc * pi/2) * horizontal speed to get vertical speed, and then solve for gravity required to have the appropriate height after time = distance / horizontal speed

Code:
gravity = (2 / time) * (heightDifference / time - verticalSpeed)

Hehe, now I'm too curious, so I'm continuing with my own now ;)

Trying to make use of the formular though, as mine didn't work exactly. But seemed like this didn't help. Apparently, when calculating the gravity with a height difference, the missile doesn't hit the exact spot. The deviation is larger the closer the targetpos is to origin position. Have a theory it has something to do with decimal numbers getting too low, and some data is lost
 
Level 5
Joined
Mar 5, 2015
Messages
135
Im pretty confident my formula should work. Push your code and we can take a look.

It works like a charm, when you keep recalculating the gravity for every update :) But when you only do it when you fire the missile, it's a little bit inaccurate - but so was my own. If it could work, it would be a little bit of an optimization, since you'd get rid of a whole lot of calculations.

I've pushed it (check the development branch).
 
Level 2
Joined
Jan 31, 2019
Messages
27
Im not sure if it will affect the accuracy or anything, but just a few comments:
- originPos.angleTo2d(targetPos) returns an angle for which you can already call trigonometric functions such as .cos()
- I believe ANIMATION_PERIOD is the shortest interval you can have on timers, not 0.01. Not sure what happens if you enter 0.01 anyway.
- You can use closures ( doPeriodically() ) to run the updateloop. No need for timers and adding data to them etc.
 
Level 5
Joined
Mar 5, 2015
Messages
135
Im not sure if it will affect the accuracy or anything, but just a few comments:
- originPos.angleTo2d(targetPos) returns an angle for which you can already call trigonometric functions such as .cos()
- I believe ANIMATION_PERIOD is the shortest interval you can have on timers, not 0.01. Not sure what happens if you enter 0.01 anyway.
- You can use closures ( doPeriodically() ) to run the updateloop. No need for timers and adding data to them etc.

Probably won't affect accuracy, but definitely are nice improvements! Saw them in your code as well, and it makes a lot of sense ;)
I think that for now I'll just make use of the same technique as you, by recalculating the update. Can always optimize the backend anyway, as long as the frontend parameters stays the sme.
 
Last edited:
Level 23
Joined
Jan 1, 2009
Messages
1,608
Weird that Watsuby only linked gold rush, actually all my maps contain missiles of some sort, based on Frentity. e.g. Frotty/Snowball-Fight

I believe ANIMATION_PERIOD is the shortest interval you can have on timers, not 0.01. Not sure what happens if you enter 0.01 anyway.

It's not lowest for timers, it's a threshold of when SetUnitPosition will cause a unit to be unable to move, e.g. used for ice sliding.
With 1/32 it will not, with 1/33 or 0.03 in this case it will.
Also in general it seems to be a good value for smooth movement, hence animation.
Collision checks are usually fine with higher values, I'm using 0.06, so roughly 16 checks per second, which is totally fine if you don't have high speed, small, bullet-like missiles or very thin walls.

You can use closures ( doPeriodically() ) to run the updateloop. No need for timers and adding data to them etc.

Since you are iterating over all objects of a class, the TimedLoop module should be even nicer to use as it's made for that purpose.
 
Level 5
Joined
Mar 5, 2015
Messages
135
Weird that Watsuby only linked gold rush, actually all my maps contain missiles of some sort, based on Frentity. e.g. Frotty/Snowball-Fight

It's not lowest for timers, it's a threshold of when SetUnitPosition will cause a unit to be unable to move, e.g. used for ice sliding.
With 1/32 it will not, with 1/33 or 0.03 in this case it will.
Also in general it seems to be a good value for smooth movement, hence animation.
Collision checks are usually fine with higher values, I'm using 0.06, so roughly 16 checks per second, which is totally fine if you don't have high speed, small, bullet-like missiles or very thin walls.

Since you are iterating over all objects of a class, the TimedLoop module should be even nicer to use as it's made for that purpose.

Awesome, even more stuff to get draw inspiration from! Thanks for your feedback! ;) Haven't been at it for a while now, as I've been busy lately, but getting back to work now. And neat little tricks! I have indeed been using timers with frequencies below the animation period, but that was primarily because I didn't know the exact time to generate a smooth movement.

That TimedLoop is pretty neat as well. Actually implemented somthing similar myself (abstract Updater class), but that was before I knew this is existed! Will indeed just make use of this instead :D


I'm toying with the idea of making a simple version of the missile where the on-hit-action would be saved as a lambda function, instead of having to implement an abstract missile class. Not sure if it makes any sense to do in this way, but nonetheless I'll give it a shot.
 
Level 23
Joined
Jan 1, 2009
Messages
1,608
Awesome, even more stuff to get draw inspiration from! Thanks for your feedback!

You're very welcome! Spread the love :)

I'm toying with the idea of making a simple version of the missile where the on-hit-action would be saved as a lambda function, instead of having to implement an abstract missile class. Not sure if it makes any sense to do in this way, but nonetheless I'll give it a shot.

Yes, it is very reasonable. The generated code is basically the same - the dispatch just changes location.
Mostly depends on taste - in my case I started using wurst from the start - before it had closures etc. so especially my old maps have a wide mix of different practices.
@Cokemonkey11 's maps heavily use closures in many places.

Cheers
 
Level 5
Joined
Mar 5, 2015
Messages
135
You're very welcome! Spread the love :)



Yes, it is very reasonable. The generated code is basically the same - the dispatch just changes location.
Mostly depends on taste - in my case I started using wurst from the start - before it had closures etc. so especially my old maps have a wide mix of different practices.
@Cokemonkey11 's maps heavily use closures in many places.

Cheers

Good to hear that I'm not completely lost :D I'll try and see where it leads, and I'll probably request some feedback on the finished system here on Hive so that it may be interesting for others to use as well.

Of course, I take feedback all the time as the system progress on GitHub
 
Last edited:
Level 2
Joined
Dec 16, 2011
Messages
12
Dang pretty sweet seeing all of these resources!

Weird that Watsuby only linked gold rush, actually all my maps contain missiles of some sort, based on Frentity. e.g. Frotty/Snowball-Fight

Didn't know about that. That was the only map I had played recently so I was most familiar with how the game mechanics were directly translating to the code.

Not sure if it was mentioned anywhere but is there a good way to generate projectiles and throw them at certain attachment points?
With the projectile system, the projectile impacts the target unit's origin.
With a dummy projectile based off of shadowstrike/acid bomb, the projectile spawns from the caster's origin (cause dummy is spawned at caster origin).
 
Level 5
Joined
Mar 5, 2015
Messages
135
Didn't know about that. That was the only map I had played recently so I was most familiar with how the game mechanics were directly translating to the code.

Not sure if it was mentioned anywhere but is there a good way to generate projectiles and throw them at certain attachment points?
With the projectile system, the projectile impacts the target unit's origin.
With a dummy projectile based off of shadowstrike/acid bomb, the projectile spawns from the caster's origin (cause dummy is spawned at caster origin).

What I'm doing, is to make it possible to hit the unit at a certain z-offset. I believe this is the same way that Warcraft is doing it originally as well. If you go into the world editor and check out an unit there is some projectile offset thingy :)
 
Level 5
Joined
Mar 5, 2015
Messages
135
Is there any way to get this programmatically?
It would be nice to know the z-offset of chest/head/overhead/etc.

For all the vertical attachment points (not hands i.e.) you could build a system which keeps data of the attachment point's z-offset from the unit's origin, such that you could use that in a missile system. I've considered to do this several times, but just the thought of it is super tidious.
Other than that, I don't know of any solutions to get what you want :/
 
Level 2
Joined
Dec 16, 2011
Messages
12
For all the vertical attachment points (not hands i.e.) you could build a system which keeps data of the attachment point's z-offset from the unit's origin, such that you could use that in a missile system. I've considered to do this several times, but just the thought of it is super tidious.
Other than that, I don't know of any solutions to get what you want :/

Darn, alright. I think I'll go the compromise route and just use some number.
 
Status
Not open for further replies.
Top