Intercept/Look-ahead question

Blitz3D Forums/Blitz3D Programming/Intercept/Look-ahead question

Axel Wheeler(Posted 2013) [#1]
I've got some spaceships shooting at each other, but they need to aim a bit better than they do; they always shoot directly at the target rather than where the target is going to be. Here's the ideas I have for intercepting:

1. Put a pivot at the target and move it according to it's speed divided by my bullet's speed (or something like that) and hope the result is good enough.

2. Use Neraj's code as described here:

http://www.blitzbasic.com/Community/posts.php?topic=69777

3. Adapt one of the "lines intersect" functions in the code archives, some of which may return an angle, but I think mostly they just tell you if two lines intersect.

Option 2 is the leader at the moment, but it's costly in cycles, so I would probably only run it once per second per ship, and just remember the distance in front of the target for the rest of that second, if you know what I mean.

Any other ideas? Thanks in advance.


RemiD(Posted 2013) [#2]
I would position a pivot at a distance, equal to the velocity of the target ship + a random value, in front of the target ship, so that sometimes the ship will shoot a missile which will hit the target ship, and sometimes no.


Axel Wheeler(Posted 2013) [#3]
Thanks for the reply.

That was my first thought (before I found Neraj's function).

Basically, the two factors are the speed of the target and the time it will take the attacker to get there. If we ignore the change in distance caused by the target's movement (moving away or approaching) then it hopefully becomes straightforward, and probably doesn't lose much accuracy since a target approaching or moving away will move less laterally anyway, so is easier to hit.

Of course if the target is actually turning, well I'm prepared to ignore that for now at least :-)

Thanks again.


Stevie G(Posted 2013) [#4]
I use a function similar to below which converges on the answer, rather than giving exact precision. The more iterations, the more accurate. This allows you to make the AI almost perfect or total shite!

v.vehicle is the source vehicle which is shooting
t.vehicle is the target vehicle
WeaponSpeed is the bullet speed of v.vehicle
Relative should always be true so that target vehicle speed is considered
v\Model is the entity for that vehicle
v\AimPivot is a pivot which the vehicle v should be aiming at after calling this function.

Function AItarget( v.Vehicle , t.Vehicle, WeaponSpeed#, Relative = True )
	
	;relative = false if vehicle doesn't have a weapon
	
	Local Iterations, x#, y#, z#
	Local vx#, vy#, vz#, Frames#, l
	
	Select v\AIskill
		Case 1	;gallus
			Iterations = 6
		Case 2  ;average
			Iterations = 3
		Case 3 	;donkey
			Iterations = 1
	End Select
	
	;target position
	x# = EntityX( t\Model, 1 )
	y# = EntityY( t\Model, 1 )
	z# = EntityZ( t\Model, 1 )
	;target velocity
	vx# = t\VelocityX - v\VelocityX * Relative
	vy# = t\VelocityY - v\VelocityY * Relative	
	vz# = t\VelocityZ - v\VelocityZ * Relative
	;target position
	PositionEntity v\AimPivot, x + vx , y + vy , z + vz					
	
	;converge to best result									
	For l = 1 To Iterations
		Frames# = EntityDistance( v\Model, v\AimPivot ) / WeaponSpeed
		PositionEntity v\AimPivot, x + vx * Frames, y + vy * Frames , z + vz * Frames
	Next
	
End Function



Axel Wheeler(Posted 2013) [#5]
That's awesome Stevie, thanks. It looks like the same idea, but the multiple iterations makes sense. Also, I don't currently keep track of velocity x, y and z for each ship, just MoveEntity(ship,0,0,speed) but I can get that info, so this should work.

I still like the idea of only running the function once per ship per second (or so), and keeping track of the distance in front of the target. The rest of the time, just positioning the pivot in that relative location and pointing the gun/ship should be pretty good. After all, humans can't adjust their aim sixty times a second, but they can follow a target.

Oh, and I had to look up "gallus", because I are a Merican. Wikipedia has it near the end of a long list of Roman orators and such. After Gaius Cornelius Gallus, and of course the noted 19th century female bouncer Gallus Mag.

It's a Scottish expression, apparently. Gallus Mag was particularly gallus. She used to bite the earlobes off guys who refused to leave the bar. And kept the ears in a jar of alcohol behind the bar. I've learned something today. I've grown as a person. :-)


Stevie G(Posted 2013) [#6]

It's a Scottish expression, apparently. Gallus Mag was particularly gallus. She used to bite the earlobes off guys who refused to leave the bar. And kept the ears in a jar of alcohol behind the bar. I've learned something today. I've grown as a person. :-)



Me too :) I always associated 'Gallus' with brilliant or someone who loves themself etc.


Bobysait(Posted 2013) [#7]
It started with a maths tutorial to explain "how to" calculate this stuff ...
Then ... Don't know why, I started to add a ship that goes from point A to Point B, and finally, randoms ships with a missile launcher :)

Hit mouse(1) on a ship to shoot it !


Whatever, this method is similar to the others except, it calculates without iteration, the future "collision" point (so it is pretty accurate for what you need)




I just hope the maths tutorial is explicit enough.


RemiD(Posted 2013) [#8]
Bobysait>>Nice example, this can probably be useful for others things. Thanks.


Axel Wheeler(Posted 2013) [#9]
Bobysait:

Definitely one for the code archives. Both yours and Stevie's. If you do, you might want to put a quick comment line on each of those functions at the top; they are clearly very useful general game functions that people should know about.

I've, um, modified it a bit to create a simple game; I hope you don't mind. Here the player is the ship, and tries to avoid the random missiles. The missile might target the ship's eventual position (as we've been discussing) or a 50% chance of picking anywhere between that point and the current point, so slowing down won't necessarily help. I've lasted 58 seconds so far; can you do better?

It starts slow but it ramps up a bit!




Bobysait(Posted 2013) [#10]
I probably will post it on code-archive section when I'll have time to do it "well"

Nice try with your mini-game, glad my code has already found its place in this poor world ;)





[edit]

I modified the "demo". have Fun



Matty(Posted 2013) [#11]
I've found that in most of these space ship fleet action games, the ones I've designed at least, the ships usually get into some kind of patterned movement eventually that means they follow each other which makes targeting less of a headache....just aim the bullets at the ship's current position plus a random vector weighted in the direction of the target's velocity vector and hope for the best...usually works fine.


Axel Wheeler(Posted 2013) [#12]
Sure, but I'm not using vectors. Since Blitz takes care of that stuff with MoveEntity, I just rely on that. I would only be using the vector code (adding two vectors and such) for this targeting purpose. In other words, I'll have to translate pitch and yaw to vectors just to aim the gun, which carries a small cycle cost.

I figure, if I'm going to do that, I might as well use Bobysait's code since it can provide pinpoint accuracy if desired. (aces vs. donkeys, etc.). Anyway, your suggestion is another option I hadn't considered.


Bobysait(Posted 2013) [#13]
Matty : you look sarcastic in most of your comment (or it's maybe just me who does not get it right)

Well, The matter is not "how to <not> do it"
We try to give an objective answer to a problem, we're not trying to justify the reason he wanted this stuff to give him an other way to do something different.


Kryzon(Posted 2013) [#14]
I think Matty was referring to the fact that you can simulate target prediction with estimative methods and have the players perceiving them as precise methods.

In any case, there are other places with discussions on this: http://www.gamedev.net/topic/401165-target-prediction-system--target-leading/?p=3663387


Guy Fawkes(Posted 2013) [#15]
Or you can cheat and use a seconds count down system that randomly chooses between x to y seconds and shoots while your enemy constantly is using PointEntity() to point the enemy at the player. Once shot, snap him out of that function if far away enough, and make him go back to his waypoint :)


Axel Wheeler(Posted 2013) [#16]
Bobysait:

I just tried the "updated" demo. Wow! That was quick! Very cool. Try it out folks (post# 10). It's completely different.

Kryzon:

Useful link. Thanks.

Thundros:

Not sure what you mean exactly. But anyway some good methods described here.


Guy Fawkes(Posted 2013) [#17]
Well basically what I mean is.. You have a timer that randomly chooses between 2 & 5 seconds. Or x & y seconds, whichever suits you. Then, during that time frame, point the enemy towards the player, and when it finishes the timer, automatically make the enemy shoot the player. Then rinse & repeat til' your enemy is out of bullets. Then play the "click" sound once to show that he is out of bullets, then make him go back to his waypoint, or before that, look for bullets, then go back to firing at the player after having selected the correct gun for the enemy. :P Also, speed is a not needed with this type of setup as the speed is already defined by the enemy's movement speed.

It's a cheap way to do it, I know, but I follow the K.I.S.S. rule. Keep it simple, stupid. ;)


Bobysait(Posted 2013) [#18]
I think I understand what you mean, but
I've got some spaceships shooting at each other, but they need to aim a bit better than they do; they always shoot directly at the target rather than where the target is going to be


you're talking about the spaceship behavior : when it shoots / when it is shot (i.e : the IA involved)
Axel talked about estimating a position for better aiming.

So it's another subject I think, whatever it is a good subject too


Axel Wheeler(Posted 2013) [#19]
Ok, I get it. So I have fields for Ship and ShipType, with ShipType storing all the information common to all ships of that type, including a firingRate integer, which is the number of frames between firings. Each Ship then has a timeToFire integer that is set to ShipType\firingRate whenever it fires, which is whenever timeToFire drops to 0 (it decrements each frame, of course.) That seems to work for me so far, as far as timing.

Steering is a matter of pointing a pivot at the target and approaching at a certain rate per frame (based on distance from the targeting ship), then pointing the ship at the pivot. This basic method works for cruising as well (i.e. non-hunting). The only problem is that while the turning is smooth, the changes in angle are too abrupt, so I'm thinking of putting a second guide pivot in the train, so to speak. Then that pivot would make the sudden angle changes and the actual ship would appear to smoothly change angles. I hope that made sense.

For now I've stuck in a quick and dirty solution for aiming, which is as follows:

- Calculate how many frames it will take a bullet to reach the target
- Actually move the target ahead by those frames x it's speed
- Aim at that location and fire
- Move the target back where it was!

Well, I said it was dirty... :-) I suspect it's may be slower than Bobysait's method, but I need to time to benchmark both ways (and Stevie G's as well).

It is surprisingly accurate, tho. I expected it to be off when the target is approaching or receding at say, 45 degrees, but so far it's pretty much right on. The ships are chubby enough to still get hit.

You guys have been amazingly helpful, as always! I'll publish an updated demo soon.


Bobysait(Posted 2013) [#20]
You can also use a Lerp (or Slerp) function




here is an online version (html5 compiled with monkey's demo)
http://bobysait.free.fr/minigames/html5/Tourel/MonkeyGame.html


Axel Wheeler(Posted 2013) [#21]
You have a talent sir! Amazing stuff.


Stevie G(Posted 2013) [#22]
Excellent work Bobsait.


Matty(Posted 2013) [#23]
Sorry Bobysait - I wasn't trying to be sarcastic...maybe that's just how it came across...I was simply giving my own method for how I do these sorts of things...admittedly I don't know the exact type of game the Axel is trying to create (is it a fleet combat game (in which case my method is fine) or is it a simple shooter...) - I was just giving my opinion as to a method that should do the trick.


Bobysait(Posted 2013) [#24]
Ok, no problem, so it's just me who misunderstood (sorry for this, I 'm french, I might bad understand things sometimes, don't worry for this)

@Stevie G and Axel Wheeler : thanks :)


Axel Wheeler(Posted 2013) [#25]
Ok, so I've updated the demo that I had originally talked about on this thread. Everything you see is procedurally generated using the randomizer.

It now features:

- A nebula in the sky (or parts of the sky)
- A planet (with a huge black gash along the meridian. You'll see it when it rolls around. Gotta fix that texture generator.)
- Battleships with independent turrets. Sometimes they're accurate, often not. But they're a lot more accurate than they were before this thread!

You'll notice that when a ship explodes, the light reflects off the planet! Just think of it as a very bright explosion.

There are many other improvements that it needs, such as flames and smoke for the explosions, and just better 'explosion management'. Oh, and sounds. I'm not going to try to generate those! (at least not immediately.) But hopefully those will be the only loaded media.


Bobysait(Posted 2013) [#26]
MAV on "setting up the planet".


Axel Wheeler(Posted 2013) [#27]
Interesting. Doesn't do that for me, although it takes awhile. The texture generator needs optimization, and I guess it has a bug too. I'll check tomorrow. Thanks for trying...


Matty(Posted 2013) [#28]
Same - I get the same MAV running on my work machine - integrated graphics card.

If it doesn't do it on yours and yours has a dedicated graphics card make sure the texture flags are supported...often with integrated cards you can't leave off the color flag when combined with alpha in a texture flag....although I'm sure it could be something else as well...this is just from my own experience.

Ie createtexture(width,height,1+2) will work on an integrated card but createtexture(width,height,2) will not work.


Bobysait(Posted 2013) [#29]
I have no chipset (real decent graphics card) and I get the MAV, it's probably something else.

BTW : Windows 7 64 bits. If it may be relevant to the error produced.

(else, you can check if you enabled the debugger, some mistakes does not crach with or without debugguer, like peek/poke to a bank outside the banksize)


Axel Wheeler(Posted 2013) [#30]
Matty:

You may have found it. My CreateTexture for the planet was:

Local pTex=CreateTexture(2045,1024,2)

I changed it to 3. I've updated the demo.

In case that does not work, I've also put up a version without the planet, since we are primarily interested in the targeting anyway, and the planet is still pretty basic. And, like I said, it has a massive black line to be fixed.

Bobysait:

As it happens I do use banks, but those functions are also used before the planet part, so I suspect that wasn't the problem.

Thanks again!


Axel Wheeler(Posted 2013) [#31]
Whoa... Ok, two more possible issues:

1. I just noticed the "2045" instead of "2048" fat finger problem. Still, doesn't Blitz round that off to the nearest power of two? (anyway, fixed and uploaded)

2. I just read that some graphics cards can't do textures bigger than 1024. I have an old Dell Dimension E510, so I tend to assume that if my pc can run it, your's probably can too.

Either may be the issue. I've created yet another download with a smaller planet texture (1024x512).


Bobysait(Posted 2013) [#32]
Seems to run, I saw the ships

- the "help" says we can move our ship : it does work, I can rotate the camera (really too fast BTW) zoom and pause. but no moves.

- it crashes (MAV) if I hit "Space" button :)

ps : the ships are procedural too ? if so, congrats they looks really nice ^^


Axel Wheeler(Posted 2013) [#33]
Yes, it's all procedural. They are actually standard Blitz spheres, with verts modified according to a random numbers smoothly interpolated, along with a few other extrusion-type modifications.

The acceleration works for me, but it's a bit slow at first. The right mouse button is the accelerator.

As far as rotation speed, it may be that my system is so slow, so it looks perfect for me. I may need to slow it down a bit.


Bobysait(Posted 2013) [#34]
it should not be different with different systems. You should think about implementing a "time-based" algorithm.


Axel Wheeler(Posted 2013) [#35]
My understanding of delta timing may be wrong, but isn't it the case that if you are happy with 60 fps, then Blitz essentially handles timing quite well by delaying the rest of the proper frame time, as long as your cpu and video card processing take less than that. But I see a lot of code on here where people are essentially replicating the Blitz functionality. In other words, using a delay statement to use up the time that the Flip statement would have used up anyway.

Also, simply writing more efficient code should be the first approach to improving frame rate.

Also, rarely is it pointed out (or done, that I can see) that for delta timing to work you have to multiply the movement of every entity by a calculated amount. And while this does cause movement to be smooth across frames of differing lengths, the resulting change in ai behavior can be a significant trade-off. I've played racing games where if a lag occurs the cars go straight off the track. Essentially false extrapolation errors.

Is the above valid? I don't actually know that much about it, which may be clear at this point :-)

Having said all that, you're absolutely right that it would clearly be appropriate in cases like this where I intend a lot of stuff to be happening per frame. Maybe that'll be next. (But I wanna make space stations! Waa!)


Axel Wheeler(Posted 2013) [#36]
After all that I actually checked the framerate, and it's right about 16 fps, with some frames going above that. But I'm guessing the reason the camera rotation is so fast is that I'm using it to check things out so I'm looking for speed. For players it needs to be slower.

So I've now updated the demo with a slower camera pan. And I'll look into delta timing when I can...


JeeyD(Posted 2013) [#37]
Agree improving code should be very possible and top priority, bc 60fps is a special limit for the game experience. Amazing looking procedural objects btw. Well done !!


RGR(Posted 2013) [#38]
Hi AxelWheeler
I think your FPS Count is wrong! Try external benchmarking i.e. Fraps which shows that the Framerate is constant at 60 FPS
What you show is 16.666 Millisecs each Frame ... which is equivalent to 60 FPS

16 FPS does not look that smooth as the action in your demo ;-)
Demo looks very good btw.

.


Axel Wheeler(Posted 2013) [#39]
Right you are! I was showing ms/frame. It's now corrected to show fps, which drops to around 40 on my old machine although is usually near 60. Two main things cause this to happen: One, when a ship explodes and Big10p's mesh clipping function kicks in. The other occurs when the last ship of a fleet is destroyed and a new fleet is created (the actual generation of a ship design). This is ok for the demo since in a game all the ship types will be created on initialization.

Still, the splitting has to be sped up somehow. Maybe I can do that on initialization as well...

Edit: Forgot to say, Thanks for the props!


Bobysait(Posted 2013) [#40]
I think that you haven't understood in deep why the use of Delta timing.
It does not just prevent from computer runing too fast, it calibrates everything, so it also prevent computer runing too slow.

Just imagine an online game, where a player have a Hell machine
All good, the Delay will keep it to 60 fps, so he won't go 10 times faster than you :)
But ... if you have a crapy machine ... that even not runs 15 fps ... he 'll still be 4 times faster than you are.

With Delta timing, the speed of the objects is calibrate so that it runs to an amount of units "per second", and not "per loop", then it does not depend on CPU anymore, whatever the machine runs slow or fast.


BTW : the Delay function does not work for all computers, some just doesn't care about it.
(I have a computer which does care about Delay and run applications and game at max, I had to installed CrystalCPU to reduice the FSB [which was at the standard rate] manually to prevent Overheating ... else, on almost recent game, it runs like a charm, but not longer than 20 seconds ... then it reboots > probably a problem with the CPU fan wich is undersized I think)


Axel Wheeler(Posted 2013) [#41]
Yeah, that's pretty consistent with my thoughts about dt. But notice that your examples are pretty advanced, where one is syncing multiple computers. In such cases clearly dt is justified. And in general I would think anytime a game is to be published that has enough stuff running each frame to risk going longer than 15.667 ms on target machines.

But I would still think that for systems that easily handle the frame in 15.667 ms, dt is no advantage over default Blitz Flip() behavior.

Good luck with the CrystalCPU!


Bobysait(Posted 2013) [#42]
you'll have to take care about the Flip "True"
In almost cases it should work to prevent application running up to the sync rate.
But :
1/ it depends on the refresh rate of the screen. (there are lots of screen "standardised" on 100 or 120 fps)
2/ it also depends on the graphics card configuration, if the VSync is disabled (and forced disabled) then the game will not be limited at all.

Take care of this, probably with both Delay + Flip true (or VWait) you can cover almost all the machines, but for sure only delay or only Flip true is just not enough.

(And of course all this is only required for publications, if you intend to run something only for you, I imagine you have already set up your machine)