On the Efficiency of Rail Turrets

    Joined
    Jun 27, 2013
    Messages
    38
    Reaction score
    108
    • Community Content - Bronze 1
    • Legacy Citizen 4
    So, as many of you are probably aware, Rail Turrets that do not have complete 360-degree freedom of motion cause extreme CPU usage when either the turrets are too big or there are too many of them. Feed has already posted a very reasonable suggestion for how to solve this issue, however I believe that it could be taken one step further and be entirely automated.

    Let's start first with a time-cost analysis of rail turrets. When performing rail collision detection, we start with the blocks of the moving entity--the turret, and check against whatever it's docked on. I'm not entirely certain of the specifics, but it appears that Schine has managed to make this run in effectively linear time when there are no collisions, which is awesome. But, when a collision is detected, suddenly we must check every block in the turret against every block in the parent ship, and we jump into N-squared time for just one turret. Add multiple turrets into that and we're in N-cubed, which means larger vessels and turret counts are completely unusable.

    Why?

    Because a turret doesn't know when to stop trying to move in a certain direction, and so it repeatedly attempts to move to follow a target that it physically cannot, triggering an N^3 algorithm with a very large number of items to process on each frame, causing extreme processor wait times and absolutely butchering framerate. What Feed suggested above would solve this completely: a turret would rarely need to perform a worst-case collision check because of the boundaries set by the player. But I don't think there's a need to have the player do this. The turret could be coded to remember its last attitude and elevation, so when it makes an attempt to move and is blocked, it stores the attitude/elevation it tried to move to as its max for the direction it was moving (as determined by the sign of the change in current attitude/elevation), and will never attempt to move beyond said maximum/minimum until the entity it collided with is modified. This takes an N^3 algorithm and controls it with a condition that will greatly reduce the number of times it is called, vastly improving performance on large ships that use a large number of turrets.

    tl;dr version: I suggest that Rail Turrets be changed to record maximum and minimum values for both attitude and elevation and restrict movement in between these values when a collision is detected in order to reduce the number of collision checks that are called by AI-operated Rail Turrets and restore usable performance of battleship-style ships.
     
    Joined
    Jun 23, 2013
    Messages
    136
    Reaction score
    25
    • Purchased!
    • Community Content - Bronze 1
    • Legacy Citizen 2
    Very much agreed!

    Using that field of view to acquire targets and prevent collisions would be awesome. Also, it should be a hotfix asap after it's coded in and tested...
     
    Joined
    Jul 6, 2013
    Messages
    451
    Reaction score
    108
    • Purchased!
    • Community Content - Bronze 2
    • Legacy Citizen 5
    Do we have know what conditions cause these collision checks cause if we have some specifics we might also be able to engineer around them a bit?
     
    Joined
    Jun 27, 2013
    Messages
    38
    Reaction score
    108
    • Community Content - Bronze 1
    • Legacy Citizen 4
    From what I have read on the bug tracker, the only type of turret that does not cause extreme lag is one that has complete freedom of movement about both the horizontal and vertical axes. If a dev could confirm or correct me, I'd appreciate it: I believe that the collision detection is run constantly.
     

    Winterhome

    Way gayer than originally thought.
    Joined
    Jun 29, 2013
    Messages
    1,929
    Reaction score
    636
    I feel that turrets should run a collision check in all possible orientations when docked to an entity, then save the range of motion, yes, but with one minor addition. It should narrow the possible ranges of motion to be within 0.1 degrees of the collision range, in order to prevent turrets from getting stuck on blocks anyway.
     
    • Like
    Reactions: Keptick and Esarai
    Joined
    Jun 27, 2013
    Messages
    38
    Reaction score
    108
    • Community Content - Bronze 1
    • Legacy Citizen 4
    That's definitely a good idea. I considered it as my suggestion, though I felt it may be too processor-intensive for a game. State-space searches like that can get very costly very quickly. It would be possible to do it as a separate thread and mitigate impact on gameplay, but if not done properly the calculation would cause the game to hang for several seconds upon docking a turret. By having a separate thread, the visual elements could continue, and the turret could have a 'configuring' state that represents that it is still computing its ranges of motion and will not activate until finished. This system would also have to know when to recompute the range of motion and could be triggered to do so very frequently if a ship begins taking a large amount of damage, rendering the turret effectively useless while waiting for updates, hence why I went with a method that does it dynamically without state-space searching for maximum performance.
     
    Joined
    Dec 28, 2014
    Messages
    262
    Reaction score
    64
    tl;dr version: I suggest that Rail Turrets be changed to record maximum and minimum values for both attitude and elevation and restrict movement in between these values when a collision is detected in order to reduce the number of collision checks that are called by AI-operated Rail Turrets and restore usable performance of battleship-style ships.
    Not sure if I understand you - but wouldn't this affect something like a stowed turret negatively? It tries to move within the ship but cannot, and when you pop it out it doesn't bother budging since it's 'saved' that it's blocked in either direction?
     
    Joined
    Jun 27, 2013
    Messages
    38
    Reaction score
    108
    • Community Content - Bronze 1
    • Legacy Citizen 4
    The condition for performing another check is that the host has changed in some way. Moving along a rail could trigger this change each time the turret moves to a new rail block.
     
    Joined
    Jul 15, 2014
    Messages
    506
    Reaction score
    111
    A way to solve that would be an easy method to toggle AI on and off, so when you stow it the turret switches off, with the range of motion it would have while deployed saved.
     

    Keptick

    Building masochist
    Joined
    Sep 26, 2013
    Messages
    4,062
    Reaction score
    1,841
    • Councillor 2 Gold
    • Railman Gold
    • Thinking Positive Gold
    Yes, all the yes. Turrets cause way too much lag at the moment, and you present an elegant solution to fix it.
     
    Joined
    Mar 11, 2015
    Messages
    141
    Reaction score
    39
    • Community Content - Bronze 1
    • Purchased!
    I agree with the solution of the OP but there is something more to think of.
    If you have a base which could trun 360° and a barrel which could also turn 360° and than place this trurret on a ship but not on the surface but sinked in as far as possible.
    Then if the surface is not on the same level all around but has some structures on it, you would have to save min and max angle of the barrel for every step the barrel is able to turn. Could be 1° steps or 0.1° steps or anything else.
    The thing is you would have to calculate up to (if step = 1°) 360^2 = 129600 cases, and then save them for each turret. (Would be at lease 2 int16 per case = 259200 Bytes)

    Then when you have the collision map, you not only need to check if there would be a collision while actualy moving (which is very fast with such a map), you would need a pathfinding algorythm.
    F.e:
    The target is flying left and the turret knows there is a (single)block in the way if turning left, than it should move up, turn left and back down.

    Sumemd up there are three problems.
    First the pre-calculation takes time, and if you recalculate all turrets after every block you place, building with turrets docked to the ship would become impossible.

    Second a good pathfinding algorythm is needed.

    Third, every turret needs up to 250KB space on the disk and also in the RAM. That would be mangable if you only save collisions and not all values.

    EDIT:

    Just was reading it again, damn^^
    For sure the map would be 360*2 = 720 bytes or 259200 bools(bits)=32KB
     
    Last edited:
    Joined
    Jun 27, 2013
    Messages
    38
    Reaction score
    108
    • Community Content - Bronze 1
    • Legacy Citizen 4
    Precisely, Knack, hadn't really considered the extent of such a system like that, but that complexity is why I chose to suggest an algorithm that could be run with just four extra variables for min and max attitude and elevation and a pointer to the last collided object.
     
    Joined
    Mar 11, 2015
    Messages
    141
    Reaction score
    39
    • Community Content - Bronze 1
    • Purchased!
    The vertical angle should always be a function of the horizontal angle.
    An optimization would be to not use 360 1 degree steps, but 256 1.40625 degree steps.
    This way it you would save for every horizontal step one max and one min vertical angle with only one byte. So 512 Bytes would be needed, and the calculation would be 256^2 = 65536. Much better :)
    Then, if the new calculation only takes place when leaving the build mode OR when placing a block in astronaut mode and only if the block manipulation was near the turret, it could work.
    Also, if there is no limitation of the movement, nothing would have to be saved.
    Lets say your Turret could only move 45 degrees left and rigtht, than only this area has to be saved, reducing it to 130 bytes.

    Only saving min/max angle for both axis would safe space but the amount of calculations would stay the same. And I think it would be a halfhearted solution.