I was really quite disappointed about fountain hooks being removed - they were an extremely high skill, high risk high reward maneuver. It was also ridiculously fun to watch NaVi pull it off game after game in TI3 - part of what made that my favorite year for the spectator aspect of the tournament.
I honestly thought fountain hooks were a legitimate part of the game, until they were removed. They're hard to pull off. You could also sabotage your team by teleporting members with Wisp/Io to the enemy fountain. Ahh, the worst of times.
See also: 'FadeAway' grabs in League Of Legends. Very similar concept, amusing to ponder the ways in which the programmers made the same oversight: https://www.youtube.com/watch?v=WQp63SA-NZY (12s in)
Essentially, moving the target of the 'pull' while the pull is ongoing. Pudge->Fountain for DoTA, Blitz->Thresh for LoL.
The parlor trick isn't a useful feature in practice. If a user drags a Note around a bunch, drops it, and then selects undo, what they really want is to undo all the way back to its location at the beginning of the drag. They don't want to rewind the entire drag procedure one pixel at a time.
I've dealt with this issue in various tools and level editors a few times. It can be annoying. The fundamental problem is that if your tool has undo (which it should), the cleanest way to architect it is such that every state change goes through undoable operations.
But that means that even in the "middle" of an operation like dragging something, or painting a long meandering line, you need to be creating and processing individual undoable steps so that the user can see the operation as it proceeds.
But once the operation completes, if they undo, they (usually) want to undo the whole batch of them, not each tiny step. A closer-to-home example of this for most programmers is their text editor. Type a sentence quickly and then hit undo. You don't want that to just undo literally the last character.
There are two ways I know to handle this:
1. If memory is less of a concern, I keep the series of individual undoable steps and then wrap them up in a single "multi-step" undoable operation. Then, in the main undo queue, replace them with that wrapper so that they are all processed as a single operation. When you undo the wrapper, it just undoes all of its child steps in reverse order.
2. If memory is more of a concern, I add support for collapsing a series of undoable operations into a new larger one that can represent the entire aggregate change more efficiently. This is more work because you need to write separate code for each kind of operation that can be batched this way.
> Type a sentence quickly and then hit undo. You don't want that to just undo literally the last character.
I am continually irritated by this behavior.
Yes, I do want to undo one operation. If I need to go fast and have little regard for correctness I can hold the button down.
Don't make me play the game where I hit undo, it undoes the whole sentence (or several), so I hit redo to bring it all back, and then I have to click backspace 5 times to get to where I wanted. Worse when I'm using multiple cursors and doing operations of different lengths to each line.
To keep things short: Whenever you want to insert some text you need to switch to Insert mode. When you're done you Esc out back to Normal mode. Undo will undo everything you did inside the last Insert.
> To keep things short: Whenever you want to insert some text you need to switch to Insert mode. When you're done you Esc out back to Normal mode. Undo will undo everything you did inside the last Insert.
That's a more extreme version of the behavior I'm objecting to. Why would I prefer that?
Honestly the issue is mostly due to wanting a slightly smaller, but not one character, undo. I think the problem is just that the things that I view as pauses and separate actions are almost always shorter than what the undo function sees, and undo undoes enough that it's quicker to redo and backspace than retype.
Still use vim. You can use something like "5db" to delete the previous 5 words. For more precision, "5X" will delete your last five characters. And if you have a very specific use case, macros are a big help. If you have a very specific and recurring use case, you can script in vim script, ruby, perl, python (2 & 3), tcl, racket, and lua. There may well be support for others of which I am not aware.
Undo is an transactional operation... backspace five times is precisely what backspace is for and would make undo less powerful if it undid every single keystroke.
My problem is that my mental model for what is an undoable transaction is almost always smaller than the editor's, to the point where I try to undo, get surprised by how much was lost, and then redo and control+backspace until I've deleted what I need.
The sane way to do that is to split the UI and edit, so that changes in the UI (like pixels while dragging) don't enter the history. I worked on one application that did this, and the results were almost ideal.
1a. As a bonus, offer coarse undo and granular undo (where granular undo always undoes an atomic operation, and coarse undo undoes the “multi-step” operation if applicable, to the user.
You can imagine a lot of quality of life improvements built on top of that depending on your application: eg if the user holds granular undo and there are many combinable operations (eg the user drew a single stroke that is represented by hundreds of single pixel additions), you may snap to a single coarse undo. Or you can offer a visualization of the underlying operations and what they map to, etc.
That's a viable solution too, though it comes at the price of UX complexity. HN folks tend to undervalue simplicity because they love learning new features and want all the things. But often, the best user experience for the most people means sacrificing some operations that are technically useful but not enough to carry their weight.
Yup, ultimately the balance between simplicity and technical operations available will depend on one’s own specific use case.
That said, for technical applications, I think it makes sense to expose as much of your features as possible in terms of composable, atomic units and operations.
If Cmd-Z maps to a black box “undo” command, then anything on top of that will seem like it comes at an interface complexity cost.
If, however, Cmd-Z is a configurable shortcut like any other that, by default, happens to send a “undo 1 user operation” message to a “history” module, that’s a different story. Now your users can modify it to be “undo one high level operation” instead, or “undo all consecutive operations that are the same in kind”. Or perhaps they want Cmd-Z to undo the last discrete operation, and Cmd-Alt-Z to undo the last logical operation. Or maybe there’s a strong temporal dimension to their work and they want the undo logic to take that into account.
Likely not the kind of thing you’d want for a mobile photo sharing app meant for a wide audience; but maybe the kind of thing you’d want for a complex, specialized data processing tool on the desktop.
I feel like they should've just turned it into a feature. Remove the crashing bit, allow people to do the undo zooming. Not every bug needs to be completely fixed, and it's something game developers do too much. Unintended behaviour that has cool gameplay effects or are just plain fun are removed because the developer didn't intend it ... even though players like the "bug". It's one of the reasons why I really don't like Blizzard anymore, and one of the things the Warframe devs did really, really right.
That idea is the basis for the entire game of Goat Simulator: only fix crashing. Every other bug is hilarious. The game is basically a conglomeration of bugs.
Its also one of my kids' favourite games of all time