This is a sub-topic of this topic. Please keep this topic clean and only talk about this one specific issue. In this case, the balance will be changed slightly.
This specific topic is about tactical missiles
The problem
Missiles used to track their target in Supreme Commander (not Forged Alliance). As a result, the turn rate was adjusted as the missile got closer. At some point this would happen every 1 - 3 ticks, depending on the missile. A single cruiser firing missiles can therefore easily cause a dozen of these calls happening each tic. Think about those moments when you have an armada of cruisers firing in your Seton bay firing at the middle position because the rock player lost from the beach player.
In Forged Alliance the tracking of a target was removed because it appeared to be overpowered. The problem is that all the tracking logic is still applied - they did not refactor the code responsible for that. Instead, they just switched a toggle somewhere.
As soon as the tactical missile is in a straight line all future turn rate changes are a waste of execution time.
For those interested, this is an example of the code that is being executed:
local TMissileCruiseProjectile = import('/lua/terranprojectiles.lua').TMissileCruiseProjectile02
local Explosion = import('/lua/defaultexplosions.lua')
local EffectTemplate = import('/lua/EffectTemplates.lua')
TIFMissileCruise01 = Class(TMissileCruiseProjectile) {
FxAirUnitHitScale = 1.65,
FxLandHitScale = 1.65,
FxNoneHitScale = 1.65,
FxPropHitScale = 1.65,
FxProjectileHitScale = 1.65,
FxProjectileUnderWaterHitScale = 1.65,
FxShieldHitScale = 1.65,
FxUnderWaterHitScale = 1.65,
FxUnitHitScale = 1.65,
FxWaterHitScale = 1.65,
FxOnKilledScale = 1.65,
FxTrails = EffectTemplate.TMissileExhaust01,
OnCreate = function(self)
TMissileCruiseProjectile.OnCreate(self)
self:SetCollisionShape('Sphere', 0, 0, 0, 2.0)
self.MovementTurnLevel = 1
self:ForkThread( self.MovementThread )
end,
MovementThread = function(self)
self.WaitTime = 0.1
self:SetTurnRate(8)
WaitSeconds(0.3)
while not self:BeenDestroyed() do
self:SetTurnRateByDist()
WaitSeconds(self.WaitTime)
end
end,
SetTurnRateByDist = function(self)
local dist = self:GetDistanceToTarget()
-- Get the nuke as close to 90 deg as possible
if dist > 50 then
-- Freeze the turn rate as to prevent steep angles at long distance targets
WaitSeconds(2)
self:SetTurnRate(20)
elseif dist > 128 and dist <= 213 then
-- Increase check intervals
self:SetTurnRate(30)
WaitSeconds(1.5)
self:SetTurnRate(30)
elseif dist > 43 and dist <= 107 then
-- Further increase check intervals
WaitSeconds(0.3)
self:SetTurnRate(50)
elseif dist > 0 and dist <= 43 then
-- Further increase check intervals
self:SetTurnRate(100)
KillThread(self.MoveThread)
end
end,
GetDistanceToTarget = function(self)
local tpos = self:GetCurrentTargetPosition()
local mpos = self:GetPosition()
local dist = VDist2(mpos[1], mpos[3], tpos[1], tpos[3])
return dist
end,
}
TypeClass = TIFMissileCruise01
Note that at some point the missile is checked every 4 ticks.
A solution
My propose to the solution is to set the turn rate once depending on distance. This prevents the entire thread being made all together. It also prevents a lot of engine calls and distance computations. But, the missile arc will be slightly different. This is where the balance is impacted.
We'd also need to re-evaluate how Aeon T2 TMD interacts with missiles. The final behavior should be similar to the original behavior.
My question is: is it worth changing the arc slightly in order to have a simplified, more performant implementation?
I have not worked out how much this would save in terms of sim time- I'd like to hear people's opinion about it first. Just remember that any code that does nothing costs cycles that we should spent on code that actually matters - like pinging your ally on Rock that he should've made more frigates early on.