... is how software companies fail and fail and fail again to get comparatively simple stuff right. Because all they'd need to do is look at the competition.
Bear with me.
By that I mean a combination of things, but mostly the UI side. For example, I'm looking at all tasks which could be streamlined to some kind of default action with optional advanced selections.
Take the Chocobo Porter stuff. When I select those guys, I'm presented with a menu with two options: Hire a porter or tell me stuff about those porters. Only upon selecting the first option I can finally choose the destination. And in 99% of all cases I only select the first option.
So why have the options at all? Default directly to the destination selection screen when you visit a porter for the _second_ time and stuff the question at the bottom of the list (if it is really needed at that point).
Doesn't make the game any more difficult or easy but gets rid of one click you don't really need to make.
More serious: The way they're handling errors. That's where they're really bad at.
One big error: Presenting information about server status only _after_ you've already tried to log in. Not to mention this _idiotic_ way of simply throwing you back to the main screen.
Why is this idiotic? Because it screws them over even more. Think about it: Whenever you try to log in, you try to establish a connection, then some info is transmitted and after that, the connection goes through a teardown. Computationally, that's expensive.
A real _queue_ server (cluster, if needed) would give you information _in advance_ whether you should try to login or not (and also give meaningful feedback, not simply disable the "start" button, by the way). If you then choose to login, you'll be placed in a queue, regardless of the number of people in front of you. And after your number has come up, you'll be _handed off_ to your real server cluster.
Now, if you think that this solution would put more of a strain on them, consider this: You have a client in a queue and can _control_ what this client does, namely, tell the program: "Hey, we're full, you're #300, at the rate we're going it looks like 10 more minutes, ask me for a status update in 60 seconds." That does not need much bandwidth.
Contrast this with Client connects => Client hammers the server => Client gets disconnected => Client connects => ... in a nice 5 second cycle.
To summarize: The problems currently are made worse by questionable UI decisions ("Click the OK button to continue" => Why even have the OK button in the first place? Continue immediately and present the info seamlessly on the screen, there's enough space...) and by not giving enough information about server status and capacity _beforehand_.