Hi everyone, ive been pondering a bit about the problem of AI sailing into the wind (stupid morons) and obviously getting stuck and going nowhere. Id like to change that. I was hoping to have someone with in depth knowledge of the game code point me in the right direction however, as i am not quite sure which of the files in Program/Sea_AI would be most appropriate. Heres what i want to do:
The AI ingame, I think its fair to say, is fairly basic. It will generally make an assessment on whether to engage or run away (which is largely the work of the Build mod team, well done on that!), will then sail straight for the player and once its close enough, will either turn to constantly keep its broadsides pointed at the enemy (tactical situation be damned) or sail right up to your ship and board. This works well enough for the most part, as even if it doesnt stick to windward or otherwise choose its engagements, age of sail battles are generally forgiving enough for the resulting combat to still be satisfying for the player.
It seems fair to say, however, that modding the AI to be aware of where the wind is coming from and at least do things like tack upwind would involve some fairly heavy rewrites of the AI routines, and thats not even considering stuff like keeping to windward.
I have a much simpler fix for this behaviour in mind. Rather than modify the AI itself, i would like to override the AI's rudder whenever it stupidly chooses to point itself into the wind. I envision this working something like this;
The game would run a check to determine whether the AI ship's sails have stalled. This is better than checking for specific angles off the wind, and hopefully is possible to do. Once it is detected that the AI's sails have stalled, which is only possible when sailing too far into the wind, the game will then either freeze the AI ship's rudder - effectively forcing it to keep turning at whatever rate it was already turning at - or will run a check to see what side of the wind the ship is on and force the rudder to some satisfactory amount - maybe 50% or full deflection. Either way the rudder will stay forced until the ship's sails are no longer stalled.
This should produce the following result - if the wind is coming from 0 and the AI ship is sailing at 270, but starts turning to starboard to follow a player (or for whatever reason), the moment its sails stall, at say 330 degrees, its rudder will be frozen in place and it will be forced to cross the wind all the way to 30 degrees, when it will be returned control of its rudder. The AI will, of course, most likely still want to pursue whatever is upwind, and so will probably try to turn into the wind again. But since it takes time to then counteract the turning motion and then begin turning the other way again, by the time the AI begins turning to port and crosses 30 degrees again, again freezing its rudder, it will hopefully have picked up some speed and sailed a short distance upwind. Its rudder will again be frozen, this time until it crosses to 330 degrees, and the process will repeat.
The result will hopefully be that although the AI isnt trying to tack, it will be performing a very crude tacking maneuver, hopefully making some (albeit slow) headway upwind.
Now its possible that simply freezing the rudder in place will not be satisfactory, because the ship will cross the wind too slowly and pick up negative speed, only to jam the rudder in the other direction once its crossed it and again lose whatever speed it built up. In this case, it may be better to, rather than locking the rudder at current deflection, to jam the rudder to full - either by checking for which side is closer to the wind and jamming it that way (eg if you are at 330 degrees, it should jam full starboard rudder) or by detecting the current DIRECTION of rudder (port or starboard) and jamming that to full. You can increase the rudder gradually rather than suddenly or not to full to make the ship obey the new realistic rudder mechanics in build mod but either way the result should be similar.
The result in this case should hopefully be this; if you jam the rudder to the direction of the wind, the ship will always be forced to cross the wind, albeit it will turn across the wind much quicker than just keeping rudder at whatever you found it. This should do 2 things - 1 - minimize the time spent facing the wind, thus minimizing speed loss and - 2 - when the ship regains rudder control at, say, 30 degrees, the inertia mechanics in build mod should be so high at full rudder deflection that it will take a good 30 seconds for the ship to stop turning (lets say at 45 degrees it gets to 0 rudder again) and start turning back toward the wind again. Hopefully this will mean that by the time it hits 30 degrees again (but now turning to port) it will have sailed a decent 30 seconds or more upwind, gained some speed, and with the rudder again being jammed to full, now to port, it will cross the wind and repeat the process on the other side - and hopefully make some headway into the wind.
If, instead, you jam the rudder to whatever direction it is currently facing, but to full, the result will largely be the same (in order to reach, say, 330 degrees from 270, the ship had to be turning to starboard, so jamming full starboard will force it to cross the wind) but in some very rare circumstances, like if the ship was turning to starboard to follow a ship, but that ship crossed its path and now the ship is trying to turn to port instead, the ship will not be forced to cross the wind but instead will return to whatever side of the wind it was on.
Now a few more things - in order to prevent spectacular failure, no matter what method is used the rudder must always be jammed at either port or starboard, to some minimum amount. Otherwise, a ship sailing normally with 0 rudder, but suddenly facing a shift in the wind from directly ahead (unlucky but happens) will have its rudder jammed at 0 (going nowhere fast) or the program might crash. So failsafe code will be needed to make sure the rudder is always either at port or starboard (one can be randomly selected if it isnt) at either full, whatever amount you desire, or a minimum of lets say 10%. This should mean that no matter what happens, the ship will ALWAYS steer out of the wind, eventually.
Second point - why insist on crossing the wind? Wouldnt it be better if the AI sailed on one side of the wind and crossed when it got close? Yes, but this is far more complicated to implement. If you force the ship to stay on one side of the wind, it also wont be able to cross to the other side. So for example, if i jammed the rudder of a ship at 30 degrees to port, it would never be able to pass 30 degrees - it might hit a cliff and be stuck, or the player might easily take advantage. To stop this, youd have to run complicated checks for where the enemy target is, what vector to cross the wind at, and how to avoid cliffs. The result would be faster tacking, but its needless complexity.
This brings me to the final point - its quite possible that, in part of its tacking, the AI will run up against a cliff and be unable to avoid it because we jammed its rudder. The situation is unlikely, but it can occur. However, this is a small price to pay - the ship will stop against the wall, suffer some damage, but it will keep turning (because weve jammed its rudder). Once its sails stop stalling, however, it will probably try turning back into the wind, and at this point it will be forced to cross it again - AWAY from the cliff. From this point on, the path of the ship will either lead away from the cliff altogether, or, by banging into the cliff the first time, the tacking will be close to but unlikely to hit the cliff again. Hopefully this wont be much of a problem.
The code to implement all this could be quite short and simple, its just a matter of being able to check for stalling sails, jam the rudder and know the right place in the files to insert the code so that its always running on all AI ships (and not player's ship).
Please let me know what you think and how i could get this ingame!
Oh, and ah - be gentle if this is a stupid idea!
Thanks!
The AI ingame, I think its fair to say, is fairly basic. It will generally make an assessment on whether to engage or run away (which is largely the work of the Build mod team, well done on that!), will then sail straight for the player and once its close enough, will either turn to constantly keep its broadsides pointed at the enemy (tactical situation be damned) or sail right up to your ship and board. This works well enough for the most part, as even if it doesnt stick to windward or otherwise choose its engagements, age of sail battles are generally forgiving enough for the resulting combat to still be satisfying for the player.
It seems fair to say, however, that modding the AI to be aware of where the wind is coming from and at least do things like tack upwind would involve some fairly heavy rewrites of the AI routines, and thats not even considering stuff like keeping to windward.
I have a much simpler fix for this behaviour in mind. Rather than modify the AI itself, i would like to override the AI's rudder whenever it stupidly chooses to point itself into the wind. I envision this working something like this;
The game would run a check to determine whether the AI ship's sails have stalled. This is better than checking for specific angles off the wind, and hopefully is possible to do. Once it is detected that the AI's sails have stalled, which is only possible when sailing too far into the wind, the game will then either freeze the AI ship's rudder - effectively forcing it to keep turning at whatever rate it was already turning at - or will run a check to see what side of the wind the ship is on and force the rudder to some satisfactory amount - maybe 50% or full deflection. Either way the rudder will stay forced until the ship's sails are no longer stalled.
This should produce the following result - if the wind is coming from 0 and the AI ship is sailing at 270, but starts turning to starboard to follow a player (or for whatever reason), the moment its sails stall, at say 330 degrees, its rudder will be frozen in place and it will be forced to cross the wind all the way to 30 degrees, when it will be returned control of its rudder. The AI will, of course, most likely still want to pursue whatever is upwind, and so will probably try to turn into the wind again. But since it takes time to then counteract the turning motion and then begin turning the other way again, by the time the AI begins turning to port and crosses 30 degrees again, again freezing its rudder, it will hopefully have picked up some speed and sailed a short distance upwind. Its rudder will again be frozen, this time until it crosses to 330 degrees, and the process will repeat.
The result will hopefully be that although the AI isnt trying to tack, it will be performing a very crude tacking maneuver, hopefully making some (albeit slow) headway upwind.
Now its possible that simply freezing the rudder in place will not be satisfactory, because the ship will cross the wind too slowly and pick up negative speed, only to jam the rudder in the other direction once its crossed it and again lose whatever speed it built up. In this case, it may be better to, rather than locking the rudder at current deflection, to jam the rudder to full - either by checking for which side is closer to the wind and jamming it that way (eg if you are at 330 degrees, it should jam full starboard rudder) or by detecting the current DIRECTION of rudder (port or starboard) and jamming that to full. You can increase the rudder gradually rather than suddenly or not to full to make the ship obey the new realistic rudder mechanics in build mod but either way the result should be similar.
The result in this case should hopefully be this; if you jam the rudder to the direction of the wind, the ship will always be forced to cross the wind, albeit it will turn across the wind much quicker than just keeping rudder at whatever you found it. This should do 2 things - 1 - minimize the time spent facing the wind, thus minimizing speed loss and - 2 - when the ship regains rudder control at, say, 30 degrees, the inertia mechanics in build mod should be so high at full rudder deflection that it will take a good 30 seconds for the ship to stop turning (lets say at 45 degrees it gets to 0 rudder again) and start turning back toward the wind again. Hopefully this will mean that by the time it hits 30 degrees again (but now turning to port) it will have sailed a decent 30 seconds or more upwind, gained some speed, and with the rudder again being jammed to full, now to port, it will cross the wind and repeat the process on the other side - and hopefully make some headway into the wind.
If, instead, you jam the rudder to whatever direction it is currently facing, but to full, the result will largely be the same (in order to reach, say, 330 degrees from 270, the ship had to be turning to starboard, so jamming full starboard will force it to cross the wind) but in some very rare circumstances, like if the ship was turning to starboard to follow a ship, but that ship crossed its path and now the ship is trying to turn to port instead, the ship will not be forced to cross the wind but instead will return to whatever side of the wind it was on.
Now a few more things - in order to prevent spectacular failure, no matter what method is used the rudder must always be jammed at either port or starboard, to some minimum amount. Otherwise, a ship sailing normally with 0 rudder, but suddenly facing a shift in the wind from directly ahead (unlucky but happens) will have its rudder jammed at 0 (going nowhere fast) or the program might crash. So failsafe code will be needed to make sure the rudder is always either at port or starboard (one can be randomly selected if it isnt) at either full, whatever amount you desire, or a minimum of lets say 10%. This should mean that no matter what happens, the ship will ALWAYS steer out of the wind, eventually.
Second point - why insist on crossing the wind? Wouldnt it be better if the AI sailed on one side of the wind and crossed when it got close? Yes, but this is far more complicated to implement. If you force the ship to stay on one side of the wind, it also wont be able to cross to the other side. So for example, if i jammed the rudder of a ship at 30 degrees to port, it would never be able to pass 30 degrees - it might hit a cliff and be stuck, or the player might easily take advantage. To stop this, youd have to run complicated checks for where the enemy target is, what vector to cross the wind at, and how to avoid cliffs. The result would be faster tacking, but its needless complexity.
This brings me to the final point - its quite possible that, in part of its tacking, the AI will run up against a cliff and be unable to avoid it because we jammed its rudder. The situation is unlikely, but it can occur. However, this is a small price to pay - the ship will stop against the wall, suffer some damage, but it will keep turning (because weve jammed its rudder). Once its sails stop stalling, however, it will probably try turning back into the wind, and at this point it will be forced to cross it again - AWAY from the cliff. From this point on, the path of the ship will either lead away from the cliff altogether, or, by banging into the cliff the first time, the tacking will be close to but unlikely to hit the cliff again. Hopefully this wont be much of a problem.
The code to implement all this could be quite short and simple, its just a matter of being able to check for stalling sails, jam the rudder and know the right place in the files to insert the code so that its always running on all AI ships (and not player's ship).
Please let me know what you think and how i could get this ingame!
Oh, and ah - be gentle if this is a stupid idea!
Thanks!