A bug I wish I hadn't caught
roganmurley.com
roganmurley.com
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.
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?
Undo is for undoing an action, like inserting a bunch of text.
If you want to delete one character at a time backwards... use the backspace key?
Put something in the wrong place (probably via pasting, but it's not always clear to a screen editor if you pasted or just typed quickly)
This is worse when I'm using multiple cursors, which is usually me manually cleaning up some data.
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.
(see sibling comment by ‘reificator)
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.
They eventually patched it after a pro player abused it to turn a game around at the International 3[2]
It's a shame because 6 years later it's still one of the best moments I ever witnessed in the game.
[1]: https://dev.dota2.com/showthread.php?t=2989&p=11512&viewfull...
Essentially, moving the target of the 'pull' while the pull is ongoing. Pudge->Fountain for DoTA, Blitz->Thresh for LoL.
[CPU, Guest, Anonymous, Player 1, Player 2, User, Random, "", undefined]
Either this story is just an ad, or this game has been really badly build and some h4x0r is going to have a field day with this.
What do you think happens when a previously unregistered user creates an account
I got the impression it's both an ad and a poorly implemented game.
Doesn't sound that weird to me. It's sensible to iron out the core gameplay and make sure the game's worth pursuing before focusing on persistent user accounts.
Usernames change. If your username can't change, you designed your system wrong.
Systems that are heavily persisted-comment-based at least have the excuse where changing a username would invalidate old comments referencing that user, but even GitHub still lets you change your username (if you link @-references to users, please store the user's ID in the backend text and only convert it back to a username when displaying; GitHub doesn't take this step but it should).
P.S. Hacker News, I'm looking at you.
In fact, I can't name a single service I've ever used (ever!) that lets me change my username.
Facebook? Twitter? Instagram? Any of the phone-number-based social apps (which have a poorer UX because of it, but still all allow changing usernames seeing as phone numbers change)? Also I believe Skype does allow changing usernames.
Pretty sure you have to pay to do it, but there are definitely services that let you change your user name.
People transition and might not want a username based on their deadname. People get married or divorced and change their legal name, which can have ramifications on their usernames. People might just get older, and lose significance of old pseudonyms.
of course it can be used for abuse - so show the old values next to it / on their user page / etc. allow N changes / limit the frequency. etc.
this would remove one of the reasons cited: "People transition and might not want a username based on their deadname." (People go to great lengths to remove references to their "deadname" and consider any mention of it seriously offensive.)
However, despite my downvotes (-4) I am unconvinced by that argument and the other replies. I don't think it's important to do this at all.
Shortly after they had to add an email column to address the predictable customer requests, and within a few years roughly half the user base was logging on with an email address they no longer used.
Now I find most people use an email provider and I don’t see a lot of ISP style emails
break apart your user tables! if you have constraints on pieces of info, put the constraints there, not on the user!
They have a "Player" module that can likely be controlled by a human or by an "AI" module. This is good design.
The problem here is likely that IO is tightly integrated with Player and every other module as a dependency. This is what can cause the bug to occur.
Proper design is for the "Player" module to never depend on IO as a dependency...
1. the player module should be able to output the next gamestate of a game given the action and previous gamestate.
2. The AI should calculate the action when given a gamestate.
3. IO should be a function that when given gamestate, it displays it on the screen, or saves it to the DB.
4. All modules should be unaware of the other modules.
No dependencies.
Likely the fix that the poster is doing doesn't involve separating the "Player" module from all knowledge of IO, but the fix he is doing is making AI a special case in the "Player" module. This speaks to all kinds of wrong.
Following these design patterns over a long period of time leads to code that is "tech debt" heavy and messy. It's an inevitable consequence for programmers who don't know how to design things. Also note that this is normal. I would say 99% of programmers don't know this and are likely doing some garbage like using dependency injection to make every module in the system depend on IO.
Usernames are just localized, vanity UUID's for client-side pleasure.
And then the post ends there and suggests I should go play the game. But a lot of people already commented that it sounds like an ad.
It's all open source
Unless, I read that wrong
It's a nice story, and maybe you could just not grudge him a few thousand eyeballs.
The article did not promise anything, no free xp, no gold coins - it did not even explain how the game works.