Resolving a game problem.

Talk about general things concerning Forged Alliance Forever.

Moderators: FtXCommando, Ze Dogfather

Resolving a game problem.

Postby Ze_PilOt » 24 Jul 2012, 11:57

Maybe some of you, as students, wonder what can be the purpose of your math classes.
Here is a simple example of how it will help you resolve a problem in FA.

The new stealth system currently tested for 3616 make you stop tracking your target under the fog of war.

In-Com proposed that, for air, it should not stop your planes from moving, but instead moving them toward the position of where your target should be if it keep the same direction and speed.

So, how can we resolve that in the code ?

First, let's pose the problem.
prob1.jpg
prob1.jpg (3.59 KiB) Viewed 3101 times


A is our target. At the last know position, it was going on the right at a speed of 5.

B is our plane. When A go out of sight, it was going toward A at a speed of 10.

It's a 2d vector problem. And for the sake of simplifying it, let's say that B is our reference point. He is in
X = 0, Y = 0. His speed is 10.

prob2.jpg
prob2.jpg (4.99 KiB) Viewed 3101 times


In this new referential, let's say that A is position is pa(-5, 10), and his velocity vector is va(5,0) (5 units on the right from B, 0 units in Y axis). This is his position at time 0 (t0).
So, at t1, his position will be pa(0,10), at t2 pa(5,10),.....

We also known that the interception point will be on a line defined by the position and velocity of A.
So first time we need to know is the minimal time needed by B to intercept A.

if vb is the speed of B, then we've got :

Code: Select all
| pa + va * t | = t * vb


So :
Code: Select all
(pa.x + va.x * t) ^ 2 + (pa.y + va.y * t) ^ 2 = (t * vb) ^ 2


With a little transformation :

Code: Select all
(pa.x ^ 2 + pa.y ^ 2) + ( 2 * pa.x * va.x + 2 * pa.x * va.x) * t + (va.x^2 + va.y^2 - vb^2) * t^2 = 0


We now have a quadratic equation :
Code: Select all
ax^2 + bx +c = 0


I guess you had to do these things a lot at school :)

To find x :
Code: Select all
x = (-b +- sqrt(b^2 - 4ac)) / 2a.

And that's our interception time.

In our case :

Code: Select all
a = (va.x^2 + va.y^2 - vb^2)
b = ( 2 * pa.x * va.x + 2 * pa.x * va.x)
c  = (pa.x ^ 2 + pa.y ^ 2)



So in your example :

Code: Select all
a = (5^2 + 0^2 - 10^2) = (25 - 100) = -75.
b = ( 2 * -5 * -5 + 2 * -5 * 0) = ( 50 + 0) = 50.
c = (-5^2 + 10^2) = 25 + 100 = 125.


upper term :
Code: Select all
A =  (-50 -+ sqrt(50^2 -4*-75*125)
A = -50 +- 200


lower term :
Code: Select all
B = -150


So, we've got two possible interception times :
Code: Select all
tA = (-50+200) / -150 = 1.
tB = (-50-200) / -150 = 1.666.


We keep our lower time as the one we want to use.

And, indeed, if our plane goes perpendicular ( vector vb2 = (0,10)), it will intercept A at time 1.
Eventually, it can go a little to the right and get it 0.6 seconds later.

But even we can deduct that intuitively, we need to compute the position where the plane must be going (the interception point).

That will be part 2.
Nossa wrote:I've never played GPG or even heard of FA until FAF started blowing up.
User avatar
Ze_PilOt
Supreme Commander
 
Posts: 8985
Joined: 24 Aug 2011, 18:41
Location: fafland
Has liked: 18 times
Been liked: 376 times
FAF User Name: Ze_PilOt

Re: Resolving a game problem.

Postby VoiceofReason » 24 Jul 2012, 12:19

I think your making stealth less usefull if a plane is going to automatically guess a stealthed units trajectory without micro... Whats next, labs that dance on there own? Cmon!
User avatar
VoiceofReason
Priest
 
Posts: 422
Joined: 26 Sep 2011, 04:13
Has liked: 175 times
Been liked: 53 times
FAF User Name: VoRCom

Re: Resolving a game problem.

Postby Ze_PilOt » 24 Jul 2012, 12:21

Currently, a plane is going EXACTLY where the target is, following it no matter what it does (changing directions, stopping,....), with even less micro.
We are talking of attack order here, not a general behavior.

But it's not the topic to discuss it. But I bet you didn't even tried the current testing version at all.
Nossa wrote:I've never played GPG or even heard of FA until FAF started blowing up.
User avatar
Ze_PilOt
Supreme Commander
 
Posts: 8985
Joined: 24 Aug 2011, 18:41
Location: fafland
Has liked: 18 times
Been liked: 376 times
FAF User Name: Ze_PilOt

Re: Resolving a game problem.

Postby VoiceofReason » 24 Jul 2012, 12:28

"The new stealth system currently tested for 3616 make you stop tracking your target under the fog of war"


My comment follows this, not previous versions. I like the idea that autotracking is taken out in the balance
User avatar
VoiceofReason
Priest
 
Posts: 422
Joined: 26 Sep 2011, 04:13
Has liked: 175 times
Been liked: 53 times
FAF User Name: VoRCom

Re: Resolving a game problem.

Postby Plasma_Wolf » 24 Jul 2012, 12:33

As someone who studies math, all I have to say: yay for mathematics! (though this would be one of the most REALLY most basic problems I'd have to solve nowadays.

Additionally, can we get a math font on the forum? :mrgreen:
User avatar
Plasma_Wolf
Supreme Commander
 
Posts: 1335
Joined: 20 Oct 2011, 11:28
Has liked: 23 times
Been liked: 91 times
FAF User Name: Plasma_Wolf

Re: Resolving a game problem.

Postby Ze_PilOt » 24 Jul 2012, 12:40

This is very basic level, but my hope is that some young readers here will realize that what they found boring in their current math course is actually really useful in the game they play.

VoiceofReason : The current patch is just canceling all orders on the plane.
Ie you try to intercept a transport. You lose track of it.
- Previously, it was going to track it under the FoW.
- Now, it will stop doing anything.

The solution I want to test, described here. will make the plane going toward the supposed transport position if it keep the same trajectory.

I agree that, in fact, that new behavior is BETTER than the old one in this case (as the best way to catch a transport is not following it, but getting ahead of his current trajectory).
But it's also up to the guy making the transport to change his order to fool the system too.
Also, this is only for TESTING, to see what behavior is better. But I need testers for that.
Nossa wrote:I've never played GPG or even heard of FA until FAF started blowing up.
User avatar
Ze_PilOt
Supreme Commander
 
Posts: 8985
Joined: 24 Aug 2011, 18:41
Location: fafland
Has liked: 18 times
Been liked: 376 times
FAF User Name: Ze_PilOt

Re: Resolving a game problem.

Postby Ze_PilOt » 24 Jul 2012, 12:57

So.

For computing the position, this is quite simple.

We now that the intersection time is 1.

We multiply the velocity vector of A by that time :

v(1) = (5,0) * 1 = (5,0).
We now add that vector to the current position of A, to get his position at t1 :
(-5, 10) + (5, 0) = (0,10). This is our interception point a t1.

For the sake of it, we can compute our second interception point :

v(2) = (5,0) * 1.666 = (8,33, 0)
(-5,10) + (8,33,0) = (3.33, 10). That's the second interception point.

We can now move the plane toward of of those two points.

This is a solid theory, but how I translate that into real code ?

First, I've said that for the sake of simplifying the math, I make my current unit the center of the world.
In supcom lua, I already know what is my unit and what is my target.
I've got two functions :
GetPosition and GetVelocity.

These two will return me a point and a vector in X,Y,Z. I can drop Y axis (up vector) as this is a 2d problem.

I should also check the current speed of my unit.
If it's not the maximum speed possible, I should take acceleration in account. But as it's making the math more complicated (at least more expensive), I will take the blueprint speed not matter what.

If my unit is at (10,10) in the world, and (50,60) is my target position.
I first need to compute by how much I need to virtually move my target to get his relative position to my source.

in supcom lua, VDiff is the tool I need.
target - unit, so I get (40,50).

the velocity vector don't need to be changed : A velocity is a direction and a speed, it won't change unless I rotate the axis of my source unit. But as the current direction of my unit is irrelevant to my problem, I don't need to do that. (in fact, it is, as I should take the turnrate,.. in account in my calculation. But again, too complicated and expensive to compute).

Then, I need do code the math in lua, and check some cases where interception is not possible.
It's not done yet, but even if the equation will tell me when the interception won't happen, I'm pretty sure I can catch these cases before computing all that in order to optimize my code.

One of the case I can see if is my unit max speed is inferior to my target current speed, and if his velocity vector is not pointing toward it. (Meaning that the target is getting away of my unit at a superior speed, I will never catch it).
Nossa wrote:I've never played GPG or even heard of FA until FAF started blowing up.
User avatar
Ze_PilOt
Supreme Commander
 
Posts: 8985
Joined: 24 Aug 2011, 18:41
Location: fafland
Has liked: 18 times
Been liked: 376 times
FAF User Name: Ze_PilOt

Re: Resolving a game problem.

Postby uberge3k » 28 Jul 2012, 14:50

For anyone who's interested in this topic, I highly recommend this book: http://www.amazon.com/Mathematics-Progr ... 1435458869 :)

Math is cool!
Ze_PilOt wrote:If you want something to happen, do it yourself.
User avatar
uberge3k
Supreme Commander
 
Posts: 1034
Joined: 04 Sep 2011, 13:46
Has liked: 2 times
Been liked: 48 times
FAF User Name: TAG_UBER

Re: Resolving a game problem.

Postby Ze_PilOt » 28 Jul 2012, 16:00

And the working lua code.

Note that you can do that in the UI side. Meaning that you can create a UI mod that can compute interception path pretty efficiently for land, naval,...

Code: Select all
local vax, vay, vaz =  self:GetVelocity()
local tempa = self:GetPosition()
local tempb = ent:GetPosition()
local pa = VDiff(tempb, tempa)

local vb = ent:GetBlueprint().Air.MaxAirspeed / 10


local a = (math.pow(vax,2) + math.pow(vaz,2) - math.pow(vb,2))
local b = ( 2 * pa.x * vax + 2 * pa.x * vax)
local c  = (math.pow(pa.x,2) +math.pow(pa.z, 2))

discriminant =   math.pow(b,2) - (4 * a * c)

if discriminant < 0 then
   IssueClearCommands({ent})


elseif discriminant == 0 then
   t = (-b - sqrt(discriminant)) / (2*a)
   tempa.x = tempa.x + (vax * t)
   tempa.y = tempa.y
   tempa.z = tempa.z + (vaz * t)
   
   IssueClearCommands({ent})
   IssueMove({ent}, tempa)

else
   local t1 = (-b - math.sqrt(discriminant)) / (2*a)
   local t2 = (-b + math.sqrt(discriminant)) / (2*a)
   local t
   
   if t1 < t2 and t1 > 0 then
      t = t1
   else
      t = t2
   end
   
   tempa.x = tempa.x + (vax * t)
   tempa.y = tempa.y
   tempa.z = tempa.z + (vaz * t)
   
   IssueClearCommands({ent})
   IssueMove({ent}, tempa)
   
end
end


You can notice that the code is almost a copy paste of what I wrote in the first post. Took me 5 min to write (a little more to test : The airspeed in the blueprint is / 10 to get the speed in game).
Nossa wrote:I've never played GPG or even heard of FA until FAF started blowing up.
User avatar
Ze_PilOt
Supreme Commander
 
Posts: 8985
Joined: 24 Aug 2011, 18:41
Location: fafland
Has liked: 18 times
Been liked: 376 times
FAF User Name: Ze_PilOt

Re: Resolving a game problem.

Postby ozonex » 29 Jul 2012, 16:00

as I am doing my game from the beginning, I came across some interesting calculations. They are written in C#, so they are a bit different

to calculate distance, where enemy will be when bullet fall i add, to corrent enemy position, enemy direction * distance from unit * bullet speed scale * enemy velocity. This will tell us where enemy will be when bullet fall.
Code: Select all
enemyPosition = enemy1_.transform.position-barel_.transform.position;
enemyDistance = Vector3.Distance(enemy1_.transform.position,  transform.position);
enemyVelocity = enemy1_.rigidbody.velocity.magnitude;

distance_ = enemyPosition  + enemy1_.transform.forward * enemyDistance * 0.13f * enemyVelocity ;


But now i must calculate how rotate barrel to angle, when bullet will fell into good place, where enemy will be. First I had to check what is minimum and maximum angle that give us minimum and maximum range. In arty t1 70-90 degrees is ok, just tested it. This is based on strength of the shot and how quickly bullet falls by gravity.

minimum angle + maximum*inverted distance from target from 0 to 1.
Code: Select all
invertedDistance = (30-distance_.magnitude)/30);
barel_.localRotation = Quaternion.Euler(new Vector3(70.0f+(20.0f*invertedDistance , 0, 0));



next interesting thing is how to quickly turn unit, tower etc. where is the smallest path - when we rotate left or right. We can simply check angle between unit direction and target, but this dont tell us how rotate. I found answer for that in engine documentation. Ido not fully understand these calculations but it may be useful to someone :P

Code: Select all
dirA = transform.forward - Vector3.Project (transform.forward, Vector3.up);

dirB = (target.position - transform.position)*Time.deltaTime - Vector3.Project ((target.position - transform.position), Vector3.up);

angle = Vector3.Angle (dirA, dirB);

rotationAngle = angle * (Vector3.Dot (Vector3.up, Vector3.Cross (dirA, dirB)) < 0 ? -1 : 1);


rigidbody.angularVelocity = (Vector3.up * rotationAngle * 0.1f);

Time.deltaTime - frame time
transform.position - unit position
transform.forward - unit direction
Vector3.up - axis on which we want to rotate
FAF Map Editor Alpha v0.605 > Get it now!
User avatar
ozonex
Priest
 
Posts: 358
Joined: 16 Feb 2012, 20:11
Location: Poland
Has liked: 197 times
Been liked: 263 times
FAF User Name: ozonex


Return to General Discussions

Who is online

Users browsing this forum: No registered users and 1 guest