* Reduce carp migration devastation (#74608) ## About The Pull Request I'm not totally satisfied with the amount of random destruction caused by space carp wandering around, they should certainly be dangerous and annoying but the random nature of their spawning and pathfinding means that they would trap themselves in random rooms and then smash all of the machinery in there. Because they could attack any dense object they perceived as being in their way that could result in venting random gas canisters, breaking terminals, or I even once saw them destroy the supermatter cooling loop by eating the thermomachines. While the latter is pretty funny, arbitrary destruction of machines simply caused because a fish teleported into a room without you knowing isn't really very engaging and doesn't create very interesting stories. This ultimately isn't meant to be a heavily destructive event and its probability to run isn't tuned as if it is. So, a couple of changes: I reduced both the range and cooldown of the carp teleporting ability. This means that AI carp can use it to pathfind past obstacles pretty reliably and don't spend so much time smashing things, and also reduces the chances of them getting the drop on you from a location you can't see. I also added a short click cooldown to carp travelling through other carp rifts so people being teleported _to_ have more of an advantage over people ambushing them (this was already true for the carp creating the rift). Additionally I added an optional whitelist to the "attack obstacles to your pathfinding" AI script, and heavily culled the kind of obstacles that carp will attack to be ones which are mostly replaceable. They will still cause a mess and might even vent a room, but they won't smash vital infrastructure. Finally I replaced a couple of instances of `get_ranged_target_turf` with `get_ranged_target_turf_direct` for better precision, and player carp using the ability can now just click anywhere on the screen and it will jaunt in that rough direction. With the reduced range, having to click within its radius was pretty annoying. With these changes I ran the event 10 times in a row on kilo and then watched JoJo's bizzarre adventure for 90 minutes and when I came back the level of destruction seemed pretty reasonable (aside from the big hole where one of them ran into the supermatter and delaminated it, but if there were players around that wouldn't happen). ## Why It's Good For The Game This event was still just a little bit _too_ annoying. If something destroys important machines it should have happened on purpose via an event which was supposed to do that, rather than through chance. Or preferably just be player-driven. ## Changelog 🆑 balance: Carp can't teleport as far, but can do it more frequently. People who piggyback through their rifts will be blocked from attacking for a short duration (the same as the normal attack cooldown). balance: AI controlled carp will now be more selective about which objects they smash. Player controlled carp (or carp directly instructed to attack objects by people who have tamed them) can still attack whatever they like. /🆑 * Reduce carp migration devastation --------- Co-authored-by: Jacquerel <hnevard@gmail.com>
AI controllers
Introduction
Our AI controller system is an attempt at making it possible to create modularized AI that stores its behavior in datums, while keeping state and decision making in a controller. This allows a more versatile way of creating AI that doesn't rely on OOP as much, and doesn't clutter up the Life() code in Mobs.
AI Controllers
A datum that can be added to any atom in the game. Similarly to components, they might only support a given subtype (e.g. /mob/living), but the idea is that theoretically, you could apply a specific AI controller to a big a group of different types as possible and it would still work.
These datums handle both the normal movement of mobs, but also their decision making, deciding which actions they will take based on the checks you put into their SelectBehaviors proc.
If behaviors are selected, and the AI is in range, it will try to perform them. It runs all the behaviors it currently has in parallel; allowing for it to for example screech at someone while trying to attack them. As long as it has behaviors running, it will not try to generate new plans, making it not waste CPU when it already has an active goal.
They also hold data for any of the actions they might need to use, such as cooldowns, whether or not they're currently fighting, etcetera this is stored in the blackboard, more information on that below.
Blackboard
The blackboard is an associated list keyed with strings and with values of whatever you want. These store information the mob has such as "Am I attacking someone", "Do I have a weapon". By using an associated list like this, no data needs to be stored on the actions themselves, and you could make actions that work on multiple ai controllers if you so pleased by making the key to use a variable.
AI Behavior
AI behaviors are the actions an AI can take. These can range from "Do an emote" to "Attack this target until he is dead". They are singletons and should contain nothing but static data. Any dynamic data should be stored in the blackboard, to allow different controllers to use the same behaviors.
Guides:
Making Your AI: Quickly runs through how to make an ai controller for anything with a step by step development of one.