Update!
It's been a while since I've posted an update here, but rest assured, I have been working hard. This is the state of Technical Machine:
Technical Machine can log into Pokemon Online and Pokemon Lab.
It has almost all standard features supported for non-battling activity in both. It can chat in the main chat (currently only if you tell it what to say) and watch the chat for certain key phrases and highlight them for me. It can read and respond to private messages (trusted users can send TM commands via PM). It can join channels. It automatically reconnects to the server if it gets disconnected.
Technical Machine can also battle on both types of servers. It is not yet aware of timer options. It cannot play in Challenge Cup or any generation other than 4. However, it can be in any number of battles on either server simultaneously (as many as it can be in and still move fast enough not to lose by time, which is quite a large number if you set the depth of search to 1). It can either challenge a particular user or accept challenges (which can be filtered to only accept challenges from trusted users or from anyone). It cannot yet use the ladder. It has successfully used a U-turn, stall, and bulky paralysis team (performing best with the stall team, probably). It has a Baton Pass team that a bit buggy, but it's very close to using that properly, as well.
One cool new feature of Technical Machine is its team selection process. You can give it either a team file for it to use, or a directory containing only team files and other directories. If you give it a particular file, it will always use that team, but if you give it a particular directory, it will use every team file in that directory with equal probability. It searches all subdirectories for team files as well.
When it challenges a user, it randomly loads one of its allowed teams (so if you said a particular team, it just loads that one particular team, but if you said a directory, it loads a file from that directory) and uses that team to challenge. This way, when Technical Machine is the challenger, it cannot be counter-teamed, unless someone finds a way to counter-team all of its teams.
On Pokemon Lab, when Technical Machine is challenged, it sees the user who is challenging it and loads a random team and then accepts their challenge (if it wants to accept).
On Pokemon Online, due to a major flaw in their team system, you have to 'register' a team with the server. If you load a new team after being challenged, you automatically reject the other user's challenge with a "Technical Machine is busy" notice. I considered many ways to work around this problem, but ultimately I decided that the only reasonable solution is to reload a new team at the start of a battle. In other words, the process goes something like this:
- Fred challenges Technical Machine.
- Technical Machine looks at the battle settings and decides they are acceptable.
- Technical Machine accepts the challenge with whatever team it had loaded previously, since it cannot change teams.
- The battle begins, and right at the start of the battle, Technical Machine sends the team it would like to use in its next battle to the server. This way, if Technical Machine is challenged again, it will not necessarily be using the same team as the previous challenge.
The one down side of this implementation is that it means that Technical Machine can only have one pending challenge at a time (because you cannot change teams while a challenge is pending). However, Technical Machine instantly makes decisions about whether to accept an incoming challenge, so the only time there is really a potential for lots of pending challenges is when Technical Machine sends out a challenge to someone else, because silly humans take time to decide whether to accept.
The reason that all of this has taken me longer than expected is this: Rather than cobbling together something that mostly works for Pokemon Online that consists primarily of copy and pasting my old PL code and then modifying it, I carefully considered how best to support multiple servers simultaneously. The end result is code that is easy to maintain because I only have to update most things in one place, and both client implementations benefit, the code is potentially smaller and easier for the compiler to optimize because I'm saying exactly what I mean, less bug prone because I don't have implementations going out of sync, and easier to port to other servers. This means that when Pokemon Showdown comes out and I add support for that, it should be much easier and faster to get that up and going, because I already have a solid "generic client" framework laid down.
However, that still doesn't explain all of the extra time it took me (my initial estimate was that I would be done with PO-specific stuff about 3 weeks ago). The remainder of the time came from me adding a few new features and securing my networking code. I cannot trust that the server I am connecting to is both bug-free and the exact code that is in the repository. There is nothing stopping someone from creating their own custom server and claiming it is a PO / PL server. This means that if there is a security flaw in my design, and I connect to such a server, they can send me whatever kind of data they want to exploit that flaw. Therefore, I spent extra time validating a lot of information the server sends me (primarily things like the server claiming that the message it's sending is, say, 5 bytes, but then actually sending me a subset of that message that is 9 bytes, which if not coded properly leads to a
buffer overflow). I still have work to do here, but my code now has a little bit of error correction and a little bit more of error detection. If it detects an unrecoverable error in transmission, rather than trying to just keep going with data that is definitely wrong, Technical Machine just closes its connection to the server and reconnects.
My plans for the immediate future are fairly simple. I'm going to finish up the last few bugs in my PO battle implementation first. Then I will add ladder support to both PO and PL. After that, I'll add something cool that I think should have been in Shoddy Battle, Pokemon Lab, and Pokemon Online for a while now. Based on both players ratings, Technical Machine will calculate the odds of each player winning. So if a player on PO has a rating of 1250 and they are fighting a player with a rating of 1370, then if the PO rating system accurately measures players ratings, it should be possible to calculate the expected outcome. Technical Machine could use this for its initial estimation of player skill if I decide to implement my idea for yomi layered battling.
Finally, I'll probably work on a few bugs in my gen 4 implementation and add generation 5 support.