It always starts with a simple idea. “I need a chatbot for Anarchy Online!”. The following days will involve a lot of thought, and hopefully, realization that it’s a project much bigger than first anticipated. This is what happened the first time I wrote a bot from scratch for AO (written in PHP, named ‘FLWBot’, using the BeBot-updated AOChat library developped by Auno). And I knew it would happen when I started on Bot#, too.
I haven’t really changed much on FLWBot since august 2009, but it’s still doing its job, and still does some things which no other bots do. I will not go into what features that is exactly, as it’s beyond the point of this entry. I will however say that I’ve spent at least 250 hours working on that bot; And that’s a guesstimate. Several weeks with 18h days, plus some days and weeks here and there with equal dedication went into making that bot.
With all that in mind, I knew what I was getting into when I decided to start working on Bot#. Writing such a bot from scratch takes time; Especially if you decide to design your own wheel (plugin system) instead of just slapping on something from an unrelated project. The core systems take time to build.
Currently, I consider these the core systems:
- Plugin System: Allows for user-provided plugins to extend the bots feature set (or if you’re narcissistic, implement random crash points)
- BotCore API: The interface which plugins use to communicate with a single ‘master + slave’ bot cluster
- FriendsManager API: Interface used by the BotCore and core plugins to manage friends
- ChatCommand & Permission API/Handling: Simplifies the creation of chat commands within plugins, so that the developer can think of their feature set instead of how the specifics work
- InfoWindow API: Interface for easy building of ingame InfoWindows (I think vhab will end up having to make this… It’s beyond my grasp & focus area at the moment)
- Probably some more I’m forgetting right now
Each on their own, the above systems seem simple enough. But when they have to interact, cooperate, utilize eeachother… things start getting messy. Some times I end up checking if an idea works, implement it… see it works, then move on. While I should have optimized the code. When this happens enough times, there’s a lot of code which will need cleaning, optimizing, and sometimes even documentation. Example: The current implementation of the ChatCommand handler goes through a chain of three methods to find & execute the right chat command; And that’s not including the method which does the actual work. I really need to streamline that, and make it less ad-hok.
The biggest challenges right now seem to be to make the interfaces exposed to the plugins as genuine, simple and efficient as possible. I’m currently going for casting the BotCore to the respective plugin interface in order to allow the plugin developers to see which methods/attributes are related to what they want to do, for simplicity. Implementation of multiple large-footprint interfaces in the BotCore is getting messy, and I’ll have to think of a smarter way of doing it. Maybe just add an accessor, BotCore.FriendsManager which casts BotCore to IFriendsManager? Hmm… I think I’ll go do that now.
The ultimate question is: Who should benefit the simplicity, and who should benefit the features? I think the simplicity has to come from the principle of K.I.S.S. – don’t make anything more complex than it has to be.
Code should be understandable, and there shouldn’t be any unnecessary loops & hoops. The features should benefit those who use the bot: API features should benefit the plugin developers, while the bots ‘ingame feature set’ should benefit those who run the bot & chosen plugins.
Even though I knew what I was getting into, I’m hitting obstacles which I couldn’t have anticipated, and they’re taking time. I do truly look forward to when the core systems are ready for public testing, since that’s where I’ll truly get to know if my design decisions were right, sorta right, or disastrous. :)
And the ultimate point of this post – or the tl;dr version, if you will? More features often mean more complex; But it does not have to. My goal is to have the best of both worlds: Code which is easy to follow, with a large feature set for everyone to use.